使用AutoMapper

我有以下课程:

class Foo
{
    public int X[];
    public int Y[];
    public int Z[];
}

class Bar
{
    public int X;
    public int Y;
    public int Z;
}

我希望创建以下AutoMapper映射:

CreateMap<Foo,IEnumerable<Bar>>

这是将单个Foo对象映射到Bar的集合,这样Foo.X[i]Foo.Y[i]将映射到Bar[i].X和{{1} }。数组的长度将始终相同。使用内置功能的AutoMapper是否有可能?理想情况下,我希望避免以编程方式显式地映射每个成员。

作为一个额外的奖励,我还想使用Bar[i].Y和以下版本的RecognizePostfixes("Postfix")支持源代码中的后缀:

Foo
leigumeng 回答:使用AutoMapper

有了@LucianBargaoanu的pointer in the right directionthis answer的另一个问题,我得以提出一种使用ITypeConverterIEnumerable扩展方法的解决方案。

这是ITypeConverter

class TransposeConverter<TSource,TDestination> : ITypeConverter<TSource,IEnumerable<TDestination>> where TDestination : class,new()
{
    public IEnumerable<TDestination> Convert(TSource source,IEnumerable<TDestination> destination,ResolutionContext context)
    {
        // Zip all the member collections from the source object together into a single collection then map to the destination based on the property names.
        return typeof(TSource).GetProperties()
            .Select(p => ((IEnumerable)p.GetValue(source)).Cast<object>().Select(item => (item,p.Name)))
            .Zip(s => context.Mapper.Map<TDestination>(s.ToDictionary(k => k.Name,e => e.item)));
    }
}

这是Zip扩展方法:

public static IEnumerable<TResult> Zip<T,TResult>(this IEnumerable<IEnumerable<T>> collections,Func<IEnumerable<T>,TResult> resultSelector)
{
    var enumerators = collections.Select(s => s.GetEnumerator()).ToArray();
    while (enumerators.All(e => e.MoveNext()))
    {
        yield return resultSelector(enumerators.Select(e => e.Current));
    }
}

但是,这只能解决问题的第一部分。它无法解决我希望在属性名称上处理后缀的“增加的奖金”部分。为此,我提出了another question

本文链接:https://www.f2er.com/3114225.html

大家都在问