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