代码之家  ›  专栏  ›  技术社区  ›  Austin Hanson

C:将同一对象添加到两个list<object>变量时,该对象是否在进程中克隆?

  •  15
  • Austin Hanson  · 技术社区  · 16 年前

    我有类似的东西:

    // Declarations:
    List<SomeType> list1 = new List<SomeType>();
    List<SomeType> list2 = new List<SomeType>();
    
    ...
    
    SomeType something = new SomeType("SomeName");
    list1.Add(something);
    list2.Add(something);
    
    ...
    
    list1[indexOfSomething] = new SomeType("SomeOtherName");
    

    列表2中的对象没有更改…这是预期的结果吗?

    7 回复  |  直到 16 年前
        1
  •  21
  •   Can Berk Güder Pugalmuni    16 年前

    是的,但没有克隆。在分配之前,两个列表中都有相同的对象。分配之后,在两个列表中有两个唯一的对象。

    这样做:

    list1[indexOfSomething].name = "SomeOtherName";
    

    目标在 list2 也会改变的。

        2
  •  7
  •   Juliet    16 年前
    // Declarations:
    List<SomeType> list1 = new List<SomeType>();
    List<SomeType> list2 = new List<SomeType>();
    
    ...
    
    SomeType something = new SomeType("SomeName");
    list1.Add(something);
    list2.Add(something);
    

    记住,当你向列表中添加一个对象时,你实际上只是在添加一个指向该对象的指针。在本例中,list1和list2都指向内存中的同一地址。

    list1[indexOfSomething] = new SomeType("SomeOtherName");
    

    现在您已经将元素列表1分配给另一个指针。

    你不是真的克隆对象本身,而是复制恰好指向同一对象的指针。如果需要证据,请执行以下操作:

    SomeType something = new SomeType("SomeName");
    list1.Add(something);
    list2.Add(something);
    
    list1[someIndex].SomeProperty = "Kitty";
    
    bool areEqual = list1[someIndex].SomeProperty == list2[someIndex].SomeProperty;
    

    areEqual 应该是真的。指点摇滚!

        3
  •  4
  •   Fredrik Mörk    16 年前

    您不是在克隆对象;而是在两个列表中添加对同一对象的引用。但是,您的代码将其中一个列表中的引用替换为对另一个对象的引用,因此是的,这是预期的行为。

        4
  •  4
  •   Jon B    16 年前

    您将用对新对象的引用替换一个列表中的引用。如果您改为更改该对象的属性,您将看到它在两个地方都发生了更改,因为引用将保持不变。

        5
  •  3
  •   Joseph    16 年前

    是的,你不是在克隆这个物体。对象最初是通过引用添加到两个列表中的,然后在列表中为正在创建的新对象分配引用。

    这绝对是预期的结果。

        6
  •  1
  •   Jon Erickson    16 年前

    当您传递要添加的“something”对象时,您是按值传递的(默认值),而不是按引用传递的

        7
  •  0
  •   JaredPar    16 年前

    是的,这是意料之中的。只添加对对象的引用。不是引用本身或副本。