C#Confusion around对象引用列表似乎不是指同一个对象

时间:2017-07-20 16:14:30

标签: c# list object reference

我有一个有一些对象字段的类,然后我从这些字段中创建一个列表。但我对实际存在多少物体感到困惑 我认为List是一种引用类型,因此修改列表中的对象也应该修改字段

但如果我修改List&设置一个等于新对象的项目,它只更改列表,而不是字段

public class MyClass{
    public string MyProperty { get; set; } = "Default value";
}


public class TestClass{
    private MyClass objectField = new MyClass();

    public void run(){
        List<MyClass> listOfObjects = new List<MyClass> { objectField };

        //Both objectField and listOfObjects[0] have the same value
        listOfObjects[0].MyProperty = "Changed value 1st time";

        //objectField is "Default value" and listOfObjects[0] is "Changed value 2nd time"
        listOfObjects[0].MyProperty = new MyClass();
        listOfObjects[0].MyProperty = "Changed value 2nd time";
    }

    public static void Main() {
        TestClass tester = new TestClass();
        tester.run();
    }
}

为什么现在看似有2个物体呢? new是否破坏了对该字段的引用?
有没有办法让字段仍然引用我在列表中创建的新对象?

这是一个简单的示例,但我有一个很大的列表,并且不想手动将字段更新为列表中的值

listOfObjects[0] = new MyClass();
listOfObjects[0].MyProperty = "Changed value 2nd time";
objectField=listOfObjects[0];  //I want to avoid this

编辑(澄清)

  • 真实场景有许多相同基类的对象字段
  • 我想同时对我的所有字段做同样的事情(更改属性值或实例化新对象)所以我想我可以把字段放在List
  • 我仍然希望能够通过它的字段名称来引用该对象,而不仅仅是List索引,但它似乎无法完成

1 个答案:

答案 0 :(得分:1)

我将在这里做一些假设,因为你的代码通常不会编译。无论如何,通用列表&lt;&gt;在C#中,当泛型类型是类(引用)类型时,是对这些类的引用的集合,但不是指向放入其中的本地对象的直接指针。

所以基本上你有一堆类对象在内存中挂起,列表中只有对它们的引用。只要在其中一个索引上新建一个新对象和REPLACE,就会用新对象(而不是内存中的对象)替换对集合中对象的引用。本地字段仍然具有对旧对象的引用。

//E.G.
var objectField = new MyClass();
var listOfObjects = new List<MyClass>{ bjectField };

// Here you are modifying the property of the original object
listOfObjects[0].MyProperty = "1st change";

// Here you are replacing the reference to that object with
//  with a reference to a new object, so the properties are totally fresh
//  properties go with the old object, a new object has all new fields / properties
//  and references
//  also, this does not replace the reference to your local field / property
listOfObjects[0] = new MyClass();

// here you are modifying the property on the new object, not the original
listOfObjects[0].MyProperty = "2nd change";

字段或属性属于该对象。 C#中的类不是一些可以用新结构覆盖的结构,并假设字段/属性只是获取对旧字段/属性的引用。

此外,将本地字段传递给集合并不意味着您要为其指定该字段,而是为其提供对该对象的引用。即使在C ++中,您也必须指定传入指向该特定字段/属性的指针。你不能做&#34;指针魔术&#34;在C#中你可以在C或C ++中更改指向新对象的指针(你可以但是你必须做不安全的代码,除非你是与本机代码结构交互)。

TL; DR;将字段传递到集合并不意味着您将直接指向该字段的指针传递到集合中。因此,在集合中替换它不会改变您的本地字段。