所以我有两个这样的自定义复杂类型(本例中过于简化):
public class PendingProduct
{
public string Name { get; set; }
public string Description { get; set; }
public int ColorCount { get; set; }
}
假设我需要这个对象知道如何将自己转换为另一种类型:
public class Product
{
public string Name { get; set; }
public string Description { get; set; }
public ProductColors Colors { get; set;}
}
因此,当我调用一个方法将PendingProduct转换为Product时,我将执行一些自定义逻辑,将ProductColor对象的“ColorCount”数量添加到Product类。这完全过于简单,但这个类的架构在这里真的无关紧要。
我的主要问题是:
当对象的属性不同时,用于实现将一个复杂类型转换为另一个复杂类型的最佳实践方法是什么?
在现实世界中,属性非常不同,我将编写一些自定义逻辑来映射从Object A到Object B所需的内容。
显然我可以编写一个函数,它接受对象A的输入参数并返回对象B,但我正在寻找更多的“最佳实践”方法。 IConvertible会在这里发挥作用吗?有没有更像OOP的东西,我可以利用而不仅仅是编写一个功能来做我想做的事情?
对象A应该始终知道如何将自身转换为对象B.
编辑:作为旁注,在现实世界中,对象A和对象B都是实体框架4实体。我想采用“待定产品”,将其转换为新的产品实体,将其附加到数据上下文并保存。
答案 0 :(得分:19)
有很多方法可以做到这一点,但它们实际上归结为自己编写映射代码,通过反射处理它,或依赖于AutoMapper之类的预构建框架。我在另一个问题here中回答了类似的问题。
我会在这里添加它以供参考:
实际上你可以
1.Reflection
public void Map<TSource, TDestination>(TSource source, TDestination destination)
{
var props = typeof(TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance);
var type = typeof(TDestination);
foreach (var prop in props)
{
object value = prop.GetValue(source, null);
var prop2 = type.GetProperty(prop.Name);
if (prop2 == null)
continue;
if (prop.PropertyType != prop2.PropertyType)
continue;
prop2.SetValue(destination, value, null);
}
}
2.Copy构造函数
public Employee(Person person)
{
// Copy properties
}
3.显式/显式转换
public static implicit operator Employee(Person person)
{
// Build instance and return
}
4.AutoMapper
Mapper.Map<Person, Employee>(person);
5.组合3/4:
public static implicit operator Employee(Person person)
{
return Mapper.Map<Person, Employee>(person);
}
关于隐式/显式转换运算符的注释:我相信使用它们不会生成符合CLS的代码。
AutoMapper允许您自定义目标类型上不同属性的映射方式,例如:
Mapper.CreateMap<Person, Employee>()
.ForMember(e => e.Forename, o => o.MapFrom(p => p.Forename.ToLower()));
答案 1 :(得分:0)
您不想从Product中派生PendingProduct吗?
public class Product
{
public string Name { get; set; }
public string Description { get; set; }
public ProductColors Colors { get; set; }
}
public class PendingProduct : Product
{
public int ColorCount { get; set; }
}