【问题标题】:How to convert a custom complex type to another custom complex type如何将自定义复杂类型转换为另一种自定义复杂类型
【发布时间】:2011-01-14 19:38:01
【问题描述】:

所以我有两个像这样的自定义复杂类型(在这个例子中过于简化了):

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 的方法时,我将执行一些自定义逻辑,将“ColorCount”数量的 ProductColor 对象添加到 Product 类中。这完全被过度简化了,但是类的体系结构在这里真的无关紧要。

我的主要问题是:

当对象的属性不同时,实现将一种复杂类型转换为另一种复杂类型的最佳实践方法是什么?

在现实世界中,属性非常不同,我将编写一些自定义逻辑来将我需要的内容从对象 A 映射到对象 B。

显然我可以编写一个函数,它接受对象 A 的输入参数并返回对象 B,但我正在寻找一种更“最佳实践”的方法。 IConvertible 在这里发挥作用吗?有没有更类似于 OOP 的东西我可以利用,而不仅仅是编写一个函数来做我想做的事?

对象 A 应该始终知道如何将自己转换为对象 B。

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

【问题讨论】:

    标签: c# oop entity-framework entity-framework-4


    【解决方案1】:

    有很多方法可以做到这一点,但它们实际上归结为要么自己编写映射代码,通过反射处理它,要么依赖像AutoMapper 这样的预构建框架。我在另一个 SO 问题 here 中回答了类似的问题。

    我会在此处添加以供您参考:

    实际上你可以

    1.反射

    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.隐式/显式转换

    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()));
    

    【讨论】:

      【解决方案2】:

      您不想从 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; } 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-20
        • 2022-01-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多