通用C#复制构造函数

通用C#复制构造函数,c#,constructor,copy,C#,Constructor,Copy,为我的c#类编写通用复制构造函数的最佳方法是什么? 它们都继承自抽象基类,因此我可以使用反射来映射属性,但我想知道是否有更好的方法?如果可以,请避免反射。每个类都应该负责复制自己的属性,并将其进一步发送到基方法。复制构造函数基本上意味着您只有一个参数,这就是要复制的对象 另外,做深度复制,而不是浅层复制 如果你不知道什么是深拷贝和浅拷贝,那么这里的交易是: 假设您正在复制一个包含一行整数作为字段的类 浅层副本应为: public class Myclass() { private int

为我的c#类编写通用复制构造函数的最佳方法是什么?
它们都继承自抽象基类,因此我可以使用反射来映射属性,但我想知道是否有更好的方法?

如果可以,请避免反射。每个类都应该负责复制自己的属性,并将其进一步发送到基方法。

复制构造函数基本上意味着您只有一个参数,这就是要复制的对象

另外,做深度复制,而不是浅层复制

如果你不知道什么是深拷贝和浅拷贝,那么这里的交易是:

假设您正在复制一个包含一行整数作为字段的类

浅层副本应为:

public class Myclass()
{
    private int[] row;
    public MyClass(MyClass class)
    {
        this.row = class.row
    }
}
深度复制是:

public class Myclass()
{
    private int[] row;
    public MyClass(MyClass class)
    {
        for(int i = 0; i<class.row.Length;i++)
        {
            this.row[i] = class.row[i];
        }
    }
}
然后打印两行,两行打印的第4个数字的值都是5。
但是,对于深度副本,只有第一次打印时才会有这种情况,因为行没有相同的指针。

您可以通过预编译(例如使用
表达式)高效地创建带有反射的浅层副本。例如


对于深度拷贝,序列化是最可靠的方法。

这里是我正在使用的构造函数。请注意,由于基类的性质,这是一个浅层构造函数,而且相当简单。应该足够好让你开始

public partial class LocationView : Location
{
    public LocationView() {}

    // base class copy constructor
    public LocationView(Location value) {
        Type t = typeof(Location);
        PropertyInfo[] properties = t.GetProperties();
        foreach (PropertyInfo pi in properties)
        {
            pi.SetValue(this, pi.GetValue(value, null), null);
        }
    }
    public Quote Quote { get; set; }
}

您可以参考ValueInjector和fasterflect nuget软件包并使用:

public class Myclass()
{
    private string _property;
    public MyClass(MyClass obj)
    {
         this.InjectFrom(obj.DeepClone());
    }
}

所以我想澄清一下,最好是在每个类上都有一个自定义的复制构造函数来显式映射属性?我会的。写起来有多难?当然,比基于反射的方法更容易阅读。是的,我推荐这种方法。读起来并不难,写起来当然很容易,但是还有一些维护问题需要考虑。如果向类添加新属性,则需要更新复制构造函数和测试,这很容易忘记。我不同意更新复制构造函数。根据新属性的变化,我不确定您需要做的不仅仅是重新运行现有的测试。添加另一个get/set对不需要对每个get/set对进行新的单元测试。您可以使用
row.clone()
,因为C#允许克隆基元数组。上述代码不是因为
row
从未初始化而失败吗?可以使用一行:
foreach(typeof(LocationView)中的var propertyInfo.BaseType.GetProperties())propertyInfo.SetValue(这是propertyInfo.GetValue(obj_to_copy_参数,null),null);
您也可以使用字段初始值设定项只读取GetProperties一次。@chrismaric当它牺牲可读性时,我倾向于避免使用一行程序。另请参见,我提出了一个浅克隆公共属性的通用扩展为什么不使用UPDRIVES?有人能确认这是否有效吗?
public class Myclass()
{
    private string _property;
    public MyClass(MyClass obj)
    {
         this.InjectFrom(obj.DeepClone());
    }
}