我有两个实现相同接口的类。这两个类中的一个具有比另一个更多的属性。现在我正在寻找一个解决方案,用更少的属性来填充类。
实际上我可能会使用手动映射器。我知道,但这必须适用于调用此函数的每个类。我已经读过lambda expression
可能是我的解决方案,但我不知道如何为每个接口/类动态地编写这个。
我的问题是不创建新实例但使用现有实例。有没有人有想法?
答案 0 :(得分:3)
如果您不介意使用第三方工具,AutoMapper可以做得更好。
从AutoMapper文档中获取的示例:
Mapper.CreateMap<Order, OrderDto>();
OrderDto dto = Mapper.Map<OrderDto>(order);
答案 1 :(得分:2)
如果您介意使用第三方工具,则可以使用此代码段并根据需要进行调整:
public B Convert<A, B>(A element) where B : A, new()
{
//get the interface's properties that implement both a getter and a setter
IEnumerable<PropertyInfo> properties = typeof(A)
.GetProperties()
.Where(property => property.CanRead && property.CanWrite).ToList();
//create new object
B b = new B();
//copy the property values to the new object
foreach (var property in properties)
{
//read value
object value = property.GetValue(element);
//set value
property.SetValue(b, value);
}
return b;
}
答案 2 :(得分:0)
public static void BusinessObjectConverter<TTarget, TSource>(this TTarget target, TSource source)
{
//Lesen aller Properties auf der ersten Ebene
var targetProperties = typeof(TTarget)
.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.Where(prop => prop.CanWrite);
//Lesen aller Properties auf der ersten Ebene
var sourceProperties = typeof(TTarget)
.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.Where(prop => prop.CanWrite);
//Loop durch alle Properties
foreach (var item in targetProperties.Intersect(sourceProperties))
{
//Leere Werte duerfen nicht geschrieben werden
if (!string.IsNullOrEmpty(source.GetType().GetProperty(item.Name).GetValue(source, null).ToString()))
{
//Befuellen der Properties im Zielobjekt
item.SetValue(target, ValueConverter.ConvertValue(
source.GetType().GetProperty(item.Name).GetValue(source, null),
item.PropertyType),
null);
}
}
}
答案 3 :(得分:0)
由于低代表我无法添加评论,因此必须发布答案。
继Automapper回答后,手动创建映射可能会很麻烦。要动态地使用:
TDestination destination = new TDestination();
AutoMapper.Mapper.Map<TSource, TDestination>(source, destination, opts => opts.CreateMissingTypeMaps = true);
您必须记住的是确保属性名称匹配