我对C ++很有经验,但对C#来说有点新鲜。
将容器添加到容器时,是通过引用还是按值传递?
也就是说,如果我这样做:
myClass m = new myClass(0); //Assume the class just holds an int
List<myClass> myList = new List<myClass>(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);
但这似乎不是有效的语法。
答案 0 :(得分:6)
值通过值传递给Add
方法;但是,如果传递引用类型(类始终是引用类型),则值本身是引用。所以问题不在于值是通过值还是通过引用传递,而是类型是值类型还是引用类型。
class MyClass
{
public int Number { get; set; }
}
通过此声明,我们得到:
MyClass m = new MyClass();
List<MyClass> myList = new List<MyClass>();
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);
}