2013-02-03 21 views
-2

我对C++很有经验,但对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); 

但这似乎不是有效的语法。

+3

“结果会是” - 不是很难尝试自己!它是由引用btw ... –

+1

除了你从来没有说过,你的'myClass'是 - 一个参考或值类型 – horgh

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

谢谢,这正是我想要了解的。我应该更清楚地说明事情 - 我的榜样是否不是我所追求的 - 你的回答就是我一直在寻找的东西。 –