c#新对象,但不是复制对象,而是引用

本文关键字:对象 新对象 复制 引用 | 更新日期: 2023-09-27 17:52:36

我有一个类ClassA,里面有一个字符串数组。

在我的代码中,我有ClassA作为一个对象,然后我想创建另一个新的ClassA对象,但它应该将原始对象复制到新类中,并做它应该做的任何事情。

但奇怪的是,当我声明新对象时,新对象中的任何变化都会影响到原对象。

我得到这样的行为有什么原因吗?

c#新对象,但不是复制对象,而是引用

听起来你只是在复制它:

ClassA obj2 = obj1;

在这种情况下,对obj2的更改确实会反映在obj1中,因为您使用的对象只是指向内存堆中相同位置的指针。你实际上并没有复制它,你只是对它做了另一个引用。

看看这里的ICloneable接口。您需要这样的内容:

public class ClassA : ICloneable
{
    public string myString { get; set; }
    public object Clone()
    {
        var obj = new ClassA();
        obj.myString = myString;
        return myObj;
    }
}

那么你可以这样称呼它:

ClassA obj2 = (ClassA)obj1.Clone();
但是,请记住,这不是非常类型安全的。这个石膏有点乱(老实说,我还没有试过,所以它甚至可能有问题)。我认为。net还没有引入通用的ICloneable。但是写一个应该不会太难。比如:
public interface ICloneable<T>
{
    public T Clone();
}
public class ClassA : ICloneable<ClassA>
{
    public string myString { get; set; }
    public ClassA Clone()
    {
        var obj = new ClassA();
        obj.myString = myString;
        return myObj;
    }
}

可以这样调用:

ClassA obj2 = obj1.Clone<ClassA>();

或者甚至(至少稍微调整一下):

ClassA obj2 = obj1.Clone();
创建这样一个泛型接口的另一个好处是,任何给定的类都可以"克隆"到其他类型,而不仅仅是它自己。您可以在单个类上实现尽可能多的ICloneable<T>接口。所以你可以这样写:
SomeOtherClass obj3 = obj1.Clone<SomeOtherClass>();

这些都是我的想法,我没有现成的编译器来测试它,但是你明白了。

我确信这是因为你只是在新对象中设置另一个字符串数组的引用。如果你想要一个单独的字符串数组,你需要创建一个构造函数来创建一个新的字符串数组并复制字符串。

你可以重载一个构造函数,它接受一个新的ClassA对象,并复制它的参数。

public class ClassA
{
    public String SomeParam { get; set; }
    public ClassA(ClassA myoldobject)
    {
           //Logic for initializing new object.
           this.SomeParam = myoldobject.SomeParam;
    }
    public ClassA(String someparam)
    {
           this.SomeParam = someparam;
    }
}

这允许你说

ClassA one = new ClassA("Test");
ClassA two = new ClassA(one);

这是因为 -是一个引用类型,而您试图获得类型的行为。在这里查看更深入的解释。J. Richter的c#书在CLR中也有详细的解释。

如果你想复制一个引用类型,你可能需要实现一个IClonable接口,并为此调用Clone

似乎您已经将第一个对象分配给了第二个对象。

要复制一个已存在的对象,必须将其所有属性值赋给新对象,而不是将整个对象赋值,因为这样会创建对同一对象的另一个引用。

要创建ClassA的第一个实例的副本,请尝试以下操作:

ClassA = secondObject = new ClassA();
secondObject.Property1 = firstObject.Property1;
secondObject.Property2 = firstObject.Property2;
............