-2

我对 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);

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

4

1 回答 1

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

请注意,这不适用于 a 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);
}
于 2013-02-03T05:08:50.973 回答