Mapster icon indicating copy to clipboard operation
Mapster copied to clipboard

Mapster fail to use user-defined explicit or implicit conversion operators from target type

Open Orace opened this issue 2 years ago • 6 comments

From this SO question.

Given the type Id:

public class Id
{
    private readonly Guid _guid;

    public Id(Guid id) => _guid = id;

    public static implicit operator Id(Guid value) => new(value);
    public static implicit operator Guid(Id value) => value._guid;

    public override string ToString() => _guid.ToString();
}

Despite the implicit conversion Mapster fail to map a Guid to an Id:

public class PocoWithGuid
{
    public Guid Id { get; init; }
}

public class PocoWithId
{
    public Id Id { get; init; }
}

var guid = Guid.NewGuid();

var pocoWithGuid1 = new PocoWithGuid { Id = guid };
Console.WriteLine(pocoWithGuid1.Id);    // 9c29424a-3c7b-4982-b301-84cc7ac41bc6

// Guid to Id fail
var pocoWithId1 = pocoWithGuid1.Adapt<PocoWithId>();
Console.WriteLine(pocoWithId1.Id);      // 00000000-0000-0000-0000-000000000000

var pocoWithId2 = new PocoWithId { Id = new Id(guid) };
Console.WriteLine(pocoWithId2.Id);      // 9c29424a-3c7b-4982-b301-84cc7ac41bc6

// Id to Guid works
var pocoWithGuid2 = pocoWithId2.Adapt<PocoWithGuid>();
Console.WriteLine(pocoWithGuid2.Id);    // 9c29424a-3c7b-4982-b301-84cc7ac41bc6

Demo code available here.

Orace avatar Mar 29 '23 09:03 Orace

@Orace Which version of Mapster are you using?

andrerav avatar May 29 '23 23:05 andrerav

@andrerav, the last one available on NuGet: 7.3.0, the demo code run on .Net7

Orace avatar May 30 '23 03:05 Orace

Could you try the latest prerelease please?

andrerav avatar May 30 '23 03:05 andrerav

@Orace @andrerav

This is #537
Id Detect as Record

adapt Guid to Id is Not possible The following reasons:

  1. Members of Guid and Id is not match
  2. ID does not contain a constructor through which an ID can be created based on the members of the Guid

then:

  1. A new guid instance is created.
  2. Which then initializes a new instance of Id through the constructor

Having learned this, I added the constructor from the Guid to ID and everything worked.

And naming of Member TSource and parameters in ctor TDestination Must be equal according to the used Naming convention

public Id(uint a, ushort b, ushort c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
{
    _guid = new Guid(a,b, c, d, e, f, g, h, i, j, k);
}

DocSvartz avatar Sep 29 '23 15:09 DocSvartz

From then TDistination detect as class it work

DocSvartz avatar Oct 03 '23 09:10 DocSvartz

Could you try the latest prerelease please?

@andrerav, It fails with 7.4.0 too.

Orace avatar Oct 03 '23 09:10 Orace