Automapping structs

Strange issue I started seeing when converting from classes to record structs.

Servicestack 6.4 (also fails on 6.2; haven’t tried anything earlier)
DotNet 6
Ubuntu 18.04

The following simple map between record structs (or plain structs) blows up -

    public record struct Struct1
    {
        public int Value { get; set; }
    }

    public record struct Struct2
    {
        public int Value { get; set; }
    }

[TestFixture]
public class AutomappingTests
{
    [Test]
    public static void TestMapServiceStack()
    {
        var x = new Struct1 {Value = 42};

        var y = x.ConvertTo<Struct2>(); // blows up
        
        Assert.Pass()
    }

Of course, if the type is class (or plain record) this works fine; if it’s a record struct or a struct it blows up.

If you want to convert and serialize structs you’ll need to implement ToString method and string constructor, e.g:

public struct Struct1
{
    public int Value { get; set; }
    public Struct1(string value) => Value = int.Parse(value);
    public override string ToString() => $"{Value}";
}

public struct Struct2
{
    public int Value { get; set; }
    public Struct2(string value) => Value = int.Parse(value);
    public override string ToString() => $"{Value}";
}

Alternatively if you just want to be able to convert them you can just implement its implicit casting which is more efficient when its implementation exists:

public record struct Struct1
{
    public int Value { get; set; }

    public static implicit operator Struct1(Struct2 from) => 
       new() { Value = from.Value };
}

public record struct Struct2
{
    public int Value { get; set; }

    public static implicit operator Struct2(Struct1 from) => 
      new() { Value = from.Value };
}

Thanks. In my actual use case there are a dozen+ members so I was hoping for an automagic approach.

Sounds like either way I’m manually doing the mapping, unless I’m missing something here.

Thanks.

1 Like

Yeah either way implementing implicit casting is a nice way to do it as you’ll be able to assign them interchangibly:

Struct1 a = new() { Value = 2 };
Struct2 b = a;

Where you’ll be able to use them to when automapping complex nested object with ServiceStack’s ConvertTo<T> extension method.