MapsterMapper / Mapster

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

Adapt to IList<T> does not update the destination IList<T> #685

Open codelovercc opened 3 months ago

codelovercc commented 3 months ago

Mapster: 7.4.1-pre01 .Net: 8.0

Method public static TDestination Adapt<TSource,TDestination>(this TSource source, TDestination destination)

public class ArticleEntity
{
    public Guid Id { get; set; }
    public string Title { get; set; }
    public string Content {get; set;}
}

public class ArticleDto
{
    public Guid Id { get; set; }
    public string Title { get; set; }
    public string Content {get; set;}
}

public void Main()
{
   IList<ArticleDto> dtos = new List<ArticleDto>
        {
            new ArticleDto
            {
                Id = default,
                Title = "Title1",
                Content = "Content1"
            },
            new ArticleDto
            {
                Id = default,
                Title = "Title2",
                Content = "Content2"
            },
        };
    var entities = dtos.Adapt<IList<ArticleEntity>>();
    entities.First().Title = "UpdatedTitle";
    var result = entities.Adapt(dtos);
    Console.WriteLine(ReferenceEquals(result, dtos)); // False
    Console.WriteLine(ReferenceEquals(result.First(), dtos.First())); // False
    Console.WriteLine(result.First().Title == "UpdatedTitle"); // True
    Console.WriteLine(dtos.First().Title == "UpdatedTitle"); // False

    var dto = new ArticleDto
        {
            Id = Guid.NewGuid(),
            Title = "Title1",
            Content = "Content1"
        };
    var entity = dto.Adapt<ArticleEntity>();
    entity.Title = "UpdatedTitle1";
    var dtoResult = entity.Adapt(dto);
    Console.WriteLine(ReferenceEquals(dtoResult, dto)); // True
    Console.WriteLine(dtoResult.Title == "UpdatedTitle1"); // True
    Console.WriteLine(dto.Title == "UpdatedTitle1"); // True
}

After var result = entities.Adapt(dtos); ran: ReferenceEquals(result, dtos) returns false that would be ok (I think it should be true ), But ReferenceEquals(result.First(), dtos.First()) returns false that is not ok, The elements in these two IList should be the same instance. var dtoResult = entity.Adapt(dto); works well, ReferenceEquals(dtoResult, dto) returns true.

What's the issue? public static TDestination Adapt<TSource,TDestination>(this TSource source, TDestination destination) should always use the destination instance and update its values and returns the destination instance, but it does not work on IList<T>, it returns a new instance of IList<T> and creates new instance for T.