C#中的memberwiseclone - system.object

时间:2012-11-11 07:03:15

标签: c# clone

MemberwiseClone()将创建浅拷贝,它将对值类型进行逐位复制,并仅复制引用类型的引用。我们需要创建一个深层副本以获得引用类型的独立副本。还行吧。我明白了 现在我的问题是:为什么System.Object变量在调用MemberwiseClone()时会有不同的反应?

例如:

Public class Test
{
    public int x;
    public object obj;

    public Test MyClone()
    {
         return (Test) this.MemberwiseClone();
    }
}

现在在我的Main方法中访问它:

public static void Main()
{
    Test obj1 = new obj1;
     obj1.x = 1;
     obj1.obj = "x";

    Test obj2 = obj1.MyClone();
    obj2.obj = "y" 
}

这不应该将obj1.obj的值更改为y吗?由于obj是System.Object的一个实例,它显然是一个引用类型。但它不会改变 - obj1.obj给出x而obj2.obj给出y。这是为什么?

2 个答案:

答案 0 :(得分:2)

这是因为您没有更改字段obj的状态。你分配它。

public static void Main()
{
    Test obj1 = new obj1;
     obj1.x = 1;
     obj1.obj = new List<string> {"x"};

    Test obj2 = obj1.MyClone();
    ((List<string>) obj2.obj).Add("y"); //now it contains {x, y} in obj1 and obj2
}

答案 1 :(得分:0)

  1. 您的代码包含3个语法错误(无法运行)

  2. 考虑您的代码:

    public static void Main() { 测试obj1 =新的obj1; obj1.x = 1; obj1.obj =“ x”;

     Test obj2 = obj1.MyClone();
     obj2.obj = "y" 
    

    }

您的错误思考位于这里:

obj2.obj = "y" 

这不会更改obj的值,它会关联一个与非克隆实例无关的其他字符串对象。

这是因为每个字符串都是不可变的对象。不同的字符串会导致堆上的对象不同。

但是如果您设法实际上更改字符串内容小精灵,那么您将获得预期的效果。

使用不安全模式,您可以通过以下方式证明这一点:

using System.Diagnostics;

static class Program
{
    static void Main()
    {
        Test obj1 = new Test();
        obj1.x = 1;
        obj1.obj = "abc";

        Test obj2 = obj1.MyClone();

        var obj1Str = obj1.obj as string;

        ReverseString(obj1Str);

        var obj2Str = obj2.obj as string;

        Debug.Print(obj2Str); // "cba"
    }

    static unsafe void ReverseString(string str)
    {
        int i = 0;
        int j = str.Length - 1;

        fixed (char* fstr = str)
            while (i < j)
            {
                char temp = fstr[j];

                fstr[j--] = fstr[i];
                fstr[i++] = temp;
            }
    }
}

public class Test
{
    public int x;
    public object obj;

    public Test MyClone()
    {
        return (Test)MemberwiseClone();
    }
}