将类型MyType映射到MyType时出现InvalidCastException

本文关键字:MyType InvalidCastException 类型 映射 | 更新日期: 2023-09-27 18:26:50

我使用AutoMapper 2.2.1将不同的业务对象映射到视图模型。现在,如果我尝试映射具有类型为CustomList的属性的对象,我将得到一个InvalidCastExceptions(请参阅下面的代码)。异常表示CustomList不能被广播到IList。这是正确的,因为CustomList实现IReadOnlyList而不是IList

那么,为什么automapper试图以这种方式进行强制转换,以及如何修复/解决这个问题呢?

我有这些类型:

public class MyViewModel : SomeModel { //... some addtional stuff ...}
public class SomeModel {
public CustomList DescriptionList { get; internal set; }
}
public class CustomList : ReadOnlyList<SomeOtherModel> {}
public abstract class ReadOnlyList<TModel> : IReadOnlyList<TModel> {}
//map it
//aList is type of SomeModel 
var viewList = Mapper.Map<List<MyViewModel>>(aList);

将类型MyType映射到MyType时出现InvalidCastException

让类从IReadOnlyList实现很可能会导致问题。Automapper不知道如何将只读列表映射到只读列表。它创建对象的新实例,并且IReadOnlyList没有添加方法或集合初始值设定项。Automapper需要能够访问只读列表所覆盖的基础列表。这可以使用ConstructUsing方法来完成。

更新的列表模型:

public class CustomList : IReadOnlyList<string>
{
    private readonly IList<string> _List;
    public CustomList (IList<string> list)
    {
        _List = list;
    }
    public CustomList ()
    {
        _List = new List<string>();
    }
    public static CustomList CustomListBuilder(CustomList customList)
    {
        return new CustomList (customList._List);
    }
}

更新了自动映射器配置

Mapper.CreateMap<CustomList, CustomList>().ConstructUsing(CustomList.CustomListBuilder);

这是一个简单的例子,但我能够使它正确映射,并且不会抛出异常。这不是最好的代码,这样做会导致同一个列表被两个不同的只读列表引用(根据您的需求,这可能是好的,也可能不是好的)。希望这能有所帮助。