映射从 IEnumerable 继承的类型时出现问题



我在映射包含从IEnumerable继承的自定义列表的属性时遇到问题(如果我删除该继承,此示例有效)。我已将问题简化为此模型:

public interface IMyEnumerable<T> : IEnumerable<T> { }
public class MyIEnumerable<T> : IMyEnumerable<T>
{
    private readonly IEnumerable<T> _items;
    public MyIEnumerable(IEnumerable<T> items)
    {
        _items = items;
    }
    public IEnumerator<T> GetEnumerator()
    {
        return _items.GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
public class Source
{
    public List<SourceItem> Items { get; set; }
}
public class Destination
{
    public IMyEnumerable<DestinationItem> Items { get; set; }
}
public class SourceItem
{
    public string Name { get; set; }
}
public class DestinationItem
{
    public string Name { get; set; }
}

然后我尝试使用这种方式:

public class MyResolver : ValueResolver<Source, IMyEnumerable<DestinationItem>>
{
    protected override IMyEnumerable<DestinationItem> ResolveCore(Source source)
    {
        var destinationItems = Mapper.Map<List<SourceItem>, IEnumerable<DestinationItem>>(source.Items);
        return new MyIEnumerable<DestinationItem>(destinationItems);
    }
}
// Mappings
Mapper.CreateMap<Source, Destination>()
    .ForMember(x => x.Items, m => m.ResolveUsing<MyResolver>());
Mapper.CreateMap<SourceItem, DestinationItem>();
// Using the mappings
var source = // not really relevant
var destination = Mapper.Map<Destination>(source);

这给了我以下例外(为了可读性而略微编辑):

Mapping types:
MyIEnumerable`1 -> IMyEnumerable`1
MyIEnumerable`1[[DestinationItem]] -> IMyEnumerable`1[[DestinationItem]]
Destination path:
Destination.Items.Items
Source value:
MyIEnumerable`1[DestinationItem]
  ----> System.ArgumentException : Object of type System.Collections.Generic.List`1[DestinationItem] cannot be converted to type IMyEnumerable`1[DestinationItem].

知道我如何修复映射以便我可以让它工作吗?

假设如下:

var source = new Source
{
    Items = new List<SourceItem>
    {
        new SourceItem { Name = "foo" },
        new SourceItem { Name = "bar" },
        new SourceItem { Name = "cow" },
    }
};

然后进行以下工作:

// Method 1: Straight up mapping the collections: 
Mapper.CreateMap<List<SourceItem>, IMyEnumerable<DestinationItem>>()
    .ConstructUsing(list => new MyEnumerable<DestinationItem>(list.ConvertAll(Mapper.Map<SourceItem, DestinationItem>)));
// Method 2: Ignore the property and do it ourselves after the rest of the mapping:
Mapper.CreateMap<Source, Destination>()
    .ForMember(q => q.Items, r => r.Ignore())
    .AfterMap((s, d) => d.Items = new MyEnumerable<DestinationItem>(
            s.Items.Select(Mapper.Map<SourceItem, DestinationItem>)));
由于

List<T>IEnumerable<T>IMyEnumerable<T>之间的协方差和逆变的某种组合,似乎没有其他方法起作用

相关内容

  • 没有找到相关文章

最新更新