C#容器通过引用或值初始化?
我对C ++很有经验,但对C#来说有点新鲜。
将对象添加到容器时,它们是通过引用还是按值传递的?
也就是说,如果我这样做:
myClass m = new myClass(0); //Assume the class just holds an int List myList = new List(1); myList.Add(m); myList[0] += 1; Console.WriteLine(m); Console.WriteLine(myList[0]);
结果是:
0 1
还是会的?
1 1
?
如果是前者,那怎么能让我做到后者呢? 我的第一直觉是做类似的事情
myClass ref mref = m; Console.WriteLine(mref);
但这似乎不是有效的语法。
该值通过值传递给Add
方法; 但是,如果传递引用类型(类始终是引用类型),则值本身是引用。 所以问题不在于值是通过值还是通过引用传递,而是类型是值类型还是引用类型。
class MyClass { public int Number { get; set; } }
通过此声明,我们得到:
MyClass m = new MyClass(); List myList = new List (); myList.Add(m); myList[0].Number += 1; Console.WriteLine(myList[0].Number); // Displays 1 Console.WriteLine(m.Number); // Displays 1 myList[0].Number += 1; Console.WriteLine(myList[0].Number); // Displays 2 Console.WriteLine(m.Number); // Displays 2
请注意,这不适用于struct
,因为myList[0]
返回的值将是存储在列表中的值的副本。 += 1
只会增加此临时副本的Number
属性,因此除了消耗几个处理器周期之外没有其他影响。 因此,仅创建不可变结构是一个很好的建议。
如果要直接显示对象,请覆盖ToString
class MyClass { public int Number { get; set; } public override string ToString() { return Number.ToString(); } }
现在,你可以写
myList[0].Number += 1; Console.WriteLine(myList[0]); Console.WriteLine(m);
您甚至可以使myList[0] += 1
与运算符重载一起工作。 在MyClass
声明
public static MyClass operator +(MyClass m, int i) { m.Number += i; return m; }
但这有点奇怪,除非你的类代表一个数字,但在这种情况下,一个不可变的struct
将是首选的,因为数字通常被认为是不可变的值类型。
public static MyStruct operator +(MyStruct m, int i) { return new MyStruct(m.Number + i); }