MapsterMapper / Mapster

A fast, fun and stimulating object to object Mapper
MIT License
4.25k stars 326 forks source link

Issue: Inconsistent result for Select and IEnumrable with polymorphism #613

Open LangSensei opened 11 months ago

LangSensei commented 11 months ago

Assume with the following data structure:

public class BaseClass
{
    private readonly string[] parameters1;

    public BaseClass(string[] parameters1)
    {
        this.parameters1 = parameters1;
    }

    public IReadOnlyCollection<string> Parameters1 => this.parameters1;
}

public class DerivedClass : BaseClass
{
    private readonly string[] parameters2;

    public DerivedClass(string[] parameters1, string[] parameters2)
        : base(parameters1)
    {
        this.parameters2 = parameters2;
    }

    public IReadOnlyCollection<string> Parameters2 => this.parameters2;
}

public class BaseClassDto
{
    public BaseClassDto(IEnumerable<string> parameters1)
    {
        this.Parameters1 = parameters1.ToList().AsReadOnly();
    }

    public ReadOnlyCollection<string> Parameters1 { get; }
}

public class DerivedClassDto : BaseClassDto
{
    public DerivedClassDto(IEnumerable<string> parameters1, IEnumerable<string> parameters2)
        : base(parameters1)
    {
        this.Parameters2 = parameters2.ToList().AsReadOnly();
    }

    public ReadOnlyCollection<string> Parameters2 { get; }
}

Test codes:

public void Test()
{
    TypeAdapterConfig<BaseClass, BaseClassDto>.NewConfig()
        .Include<DerivedClass, DerivedClassDto>();

    TypeAdapterConfig<BaseClass, BaseClassDto>.NewConfig()
        .MapWith(src =>
            new BaseClassDto(src.Parameters1.ToList()));

    TypeAdapterConfig<DerivedClass, BaseClassDto>.NewConfig()
        .Include<DerivedClass, DerivedClassDto>()
        .MapWith(src =>
            new DerivedClassDto(src.Parameters1.ToList(), src.Parameters2.ToList()));

    List<BaseClass> baseClasses = new List<BaseClass>
    {
        new DerivedClass(new string[] { "123" }, new string[] { "123" }),
        new BaseClass(new string[] { "123" })
    };

    var baseClassDtos = baseClasses.Select(bc => bc.Adapt<BaseClassDto>()).ToList();

    Console.WriteLine(JsonConvert.SerializeObject(baseClassDtos));

    baseClassDtos = baseClasses.Adapt<List<BaseClassDto>>();

    Console.WriteLine(JsonConvert.SerializeObject(baseClassDtos));
}

Result:

[{"Parameters2":["123"],"Parameters1":["123"]},{"Parameters1":["123"]}]
[{"Parameters1":["123"]},{"Parameters1":["123"]}]