And*_*ell -2 c# containers reference
我对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]);
Run Code Online (Sandbox Code Playgroud)
结果会是:
0
1
Run Code Online (Sandbox Code Playgroud)
还是会的?
1
1
Run Code Online (Sandbox Code Playgroud)
?
如果是前者,那怎么能让我做到后者呢?我的第一直觉是做类似的事情
myClass ref mref = m;
Console.WriteLine(mref);
Run Code Online (Sandbox Code Playgroud)
但这似乎不是有效的语法.
该值通过值传递给Add方法; 但是,如果传递引用类型(类始终是引用类型),则值本身是引用.所以问题不在于值是通过值还是通过引用传递,而是类型是值类型还是引用类型.
class MyClass
{
public int Number { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
通过此声明,我们得到:
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
Run Code Online (Sandbox Code Playgroud)
请注意,这不适用于a struct,因为返回的值myList[0]将是存储在列表中的值的副本.将+= 1只会递增Number该临时副本的属性,因而具有比消耗几个处理器周期没有其他作用.因此,仅创建不可变结构是一个很好的建议.
如果要直接显示对象,请覆盖 ToString
class MyClass
{
public int Number { get; set; }
public override string ToString()
{
return Number.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,你可以写
myList[0].Number += 1;
Console.WriteLine(myList[0]);
Console.WriteLine(m);
Run Code Online (Sandbox Code Playgroud)
您甚至可以myList[0] += 1使用操作员超载来完成工作.在MyClass声明
public static MyClass operator +(MyClass m, int i)
{
m.Number += i;
return m;
}
Run Code Online (Sandbox Code Playgroud)
但这有点奇怪,除非你的类代表一个数字,但在这种情况下,一个不可变的struct首选,因为数字通常被认为是不可变的值类型.
public static MyStruct operator +(MyStruct m, int i)
{
return new MyStruct(m.Number + i);
}
Run Code Online (Sandbox Code Playgroud)