使用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].XBar[i].Y。数组的长度将始终相同。使用内置功能的AutoMapper是否可以做到这一点?理想情况下,我希望避免以编程方式显式映射每个成员。

作为额外的奖励,我还想使用RecognizePostfixes("Postfix")和以下版本的Foo:支持源代码上的修补程序

class Foo
{
public int XPostfix[];
public int YPostfix[];
public int ZPostfix[];
}

通过@LucianBargaoanu在正确方向上的指针,再加上另一个问题的答案,我能够使用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));
}
}

然而,这只解决了问题的第一部分。它没有解决我希望处理属性名称后缀的"附加奖金"部分。我对此提出了另一个问题。

最新更新