2011-01-14 96 views
8

所以,我有两个自定义复杂类型像这样(简单化了这个例子):如何自定义复杂类型转换为另一种自定义的复杂类型

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转化为产品的方法,我会执行,增加了“ColorCount” ProductColor对象数量商品类的一些定制逻辑。这是完全过分简化的,但是这个类的架构在这里是非常不相关的。

我的主要问题是什么,是这样的:

什么是用于实现一个复杂类型的转换到另一个复杂类型时,对象的属性不同的最佳实践方法?

在现实世界中,产品的性能有很大的不同,我会写一些自定义的逻辑来图是我从对象需要对象B.

很显然,我可以只写一个函数,该函数的输入参数的对象A并返回对象B,但我正在寻找更“最佳实践”的方法。 IConvertible会在这里发挥作用吗?是否还有更多类似OOP的东西可以利用,而不仅仅是写一个函数来做我想要的东西?

对象A应该总是知道如何将其转换为Object B.

编辑:作为一个方面说明,在现实世界中,对象A和对象B都是实体框架4实体。我想采取“待定产品”,将其转换为新的产品实体,将其附加到数据上下文并保存。

回答

18

有很多方法可以完成,但他们真的归结为自己编写映射代码,通过反射来处理它,或者依赖预构建的框架(如AutoMapper)。我在另一个SO问题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.复印构造

public Employee(Person person) 
{ 
    // Copy properties 
} 

3.Implicit /显式转换

public static implicit operator Employee(Person person) 
{ 
    // Build instance and return 
} 

4.AutoMapper

Mapper.Map<Person, Employee>(person); 

5.Combination 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())); 
0

难道你不希望从产品中获得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; } 
}