简体   繁体   English

C# 中的 memberwiseclone - system.object

[英]memberwiseclone in C# - system.object

MemberwiseClone() will create shallow copy, which will do a bit-by-bit copy of a value type and only copy the references of a reference type. MemberwiseClone()将创建浅拷贝,它将对值类型进行逐位复制,并且只复制引用类型的引用。 We would need to create a deep copy to have an independent copy of a reference type.我们需要创建一个深层副本来拥有一个引用类型的独立副本。 This is ok.还行吧。 I get this.我明白了。 Now my question is: why does a System.Object variable react differently when MemberwiseClone() is called?现在我的问题是:为什么System.Object变量在调用 MemberwiseClone() 时会有不同的反应?

Eg:例如:

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

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

Now access this in my Main method:现在在我的 Main 方法中访问它:

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

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

Should this not change the value of obj1.obj to y?这不应该将obj1.obj的值obj1.obj为 y 吗? Since obj is an instance of System.Object which is obviously a reference type.由于 obj 是System.Object一个实例,它显然是一个引用类型。 But it does not change - obj1.obj gives x and obj2.obj gives y.但它并没有改变obj1.obj给出 x, obj2.obj给出 y。 Why is this?为什么是这样?

It's because you don't change state of field obj .这是因为您没有更改字段obj状态。 You assign it.分配它。

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. your code contains 3 syntax errors (this cannot run)您的代码包含 3 个语法错误(这无法运行)

  2. considering your code:考虑您的代码:

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

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

    } }

your wrong thinking lies here:你的错误想法在这里:

obj2.obj = "y" 

this does not change the value of obj, it assings a different string object which is not related to the non-cloned instance.这不会改变 obj 的值,它会分配一个与非克隆实例无关的不同字符串对象。

this is because every string is an immutable object.这是因为每个字符串都是一个不可变对象。 a different string results in a different object on the heap.不同的字符串在堆上产生不同的对象。

But if you actually manage to change the string content itself, then you get the expected effect.但是如果你真的设法改变了字符串内容本身,那么你就会得到预期的效果。

using unsafe mode you can prove it this way:使用不安全模式,你可以这样证明:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM