将数据从一个对象复制到另一个具有有限属性的对象

时间:2016-05-23 18:29:34

标签: c#

除第三方映射器应用程序(如Automapper)外,将数据从一个对象复制到另一个具有有限属性的对象(不完全是克隆任务)的最佳方法是什么。

Customer
{
   string Name { get; set; }
   string SSN { get; set; }
   object Addresses { get; set; }
}

to 

CustomerData
{
   string Name { get; set; }
   object Addresses { get; set; }
}

例如,我想将Customer复制到CustomerData(Addressses对象可能是嵌套对象,对象可能有更多属性)。当然,这会缩短以用于演示目的。客户中有很多字段我不想复制到CustomerData。

3 个答案:

答案 0 :(得分:1)

使用ToOtherType方法非常短customer.ToCustomerData()并且应该很快(与反射之类的奇怪事物相比)。

//ToOtherType method
public CustomerData ToCustomerData(){
    var customerData = new CustomerData();
    customerData.Name = Name;
    customerData.Addresses = Addresses;
    return customerData;
}

使用显式或隐式运算符可以编写更短的代码:CustomerData cd = customer(隐式)或CustomerData cd = (CustomerData)customer(显式)。但是要注意隐式操作符,它们可以创建有趣的调试问题。

//explicit operator
public static explicit operator CustomerData(Customer c){
    var customerData = new CustomerData();
    customerData.Name = c.Name;
    customerData.Addresses = c.Addresses;
    return customerData;
}

我选择了ToOtherType模式,它会更明显地发生了什么,特别是如果你有其他人在处理不能识别它的代码。此外,操作员模式在某些情况下(密封对象等)不起作用。

在线示例:https://dotnetfiddle.net/56p0Lh

答案 1 :(得分:0)

要复制哪些属性以及要忽略哪些属性是非常主观的。它必须是一个定制的任务。如果我这样做,在你描述的情况下,我会做以下事情:

public interface ICustomCloning{
    void CopyFrom(ICustomCloning other);
}

class Customer: ICustomCloning 
{
    string Name { get; set; }
    string SSN { get; set; }
    object Addresses { get; set; }

    public virtual void CopyFrom(ICustomCloning other){
       if(other is Customer)
       {
           var o = other as Customer;
           //copy values from o. 
           //this.Name = o.Name;
       }
       //else if(other is Addresses)
       //this.Addresses.CopyFrom(other);
    }
}
class CustomerData: ICustomCloning 
{
    string Name { get; set; }
    object Addresses { get; set; }

    public virtual void CopyFrom(ICustomCloning other){
       if(other is CustomerDa)
       {
           var o = other as CustomerData;
           //copy values from o. 
           //this.Name = o.Name;
       }
       //else if(other is Addresses)
       //this.Addresses.CopyFrom(other);
    }
}
public class Addresses: ICustomCloning{
    public virtual void CopyFrom(ICustomCloning other){
        if(other is Addresses){
            var o as Addresses;
            //Do your copy from o.
        }
        else if(other is Customer)
        //var o = (other as Customer). Addresses;
        //Do your copy from o
    }
}

答案 2 :(得分:-1)

@Chakrava对static explicit operator有正确答案,因为这些允许您将转化视为内置演员(例如CustomerData data = (CustomerData)myCustomer;)。如果您不喜欢这样做的想法,那么除了编写ToSomeType()方法之外,还有其他一些选择:

构造函数重载

public CustomerData
{
    public CustomerData(ICustomer customer)
    {
        // put your mapping code here
    }
}

var data = new CustomerData(myCustomer);

扩展方法

ToSomeType()方法类似......

public static CustomerData ToCustomerData(this Customer customer)
{
    // mapping code here

    return myCustomerData;
}

<强>继承

CustomerData
{
   string Name { get; set; }
   object Addresses { get; set; }
}

Customer : CustomerData
{
   string SSN { get; set; }
}

<强>反射

可能最好使用自动映射器或类似功能。很多使用反射的例子,所以我不会进入它。

对象初始化程序语法

不要将此折扣为一次性(想想YAGNI)或补充本文所述的其他一些机制。不过,不要乱丢你的代码。

var data = new CustomerData(){ Name = myCustomer.Name, Addresses = myCustomer.Addresses};