C# containers initialized by reference or value?

旧街凉风 提交于 2019-12-23 06:27:08

问题


I'm experienced with C++, but a little new to C#.

When you add objects to a container, are they passed by reference or by value?

That is, if I do this:

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

Will the result be:

0
1

or will it be

1
1

?

If the former, then how can get I make it do the latter? My first instinct was to do something like

myClass ref mref = m; 
Console.WriteLine(mref);

But this doesn't seem to be valid syntax.


回答1:


The value is passed by value to the Add method; however, if you pass a reference type (a class is always a reference type), then the value itself is a reference. So the question is not so much whether the value is passed by value or by reference, but if the type is a value type or a reference type.

class MyClass
{
    public int Number { get; set; }
}

With this declaration, we get:

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

Note that this would not work with a struct, because the value returned by myList[0] would be a copy of the value stored in the list. The += 1 would only increment the Number property of this temporary copy and thus have no other effect than consuming a few processor cycles. Therefore it is a good advice to create only immutable structs.


If you want to display the object directly, override ToString

class MyClass
{
    public int Number { get; set; }

    public override string ToString()
    {
        return Number.ToString();
    }
}

Now, you can write

myList[0].Number += 1;
Console.WriteLine(myList[0]);
Console.WriteLine(m);

You could even make myList[0] += 1 work with an operator overload. In MyClass declare

public static MyClass operator +(MyClass m, int i) 
{
    m.Number += i;
    return m;
}

But this is a bit weird, unless your class represents a number, but in that case an immutable struct would be preferred, as numbers are generally perceived as immutable value types.

public static MyStruct operator +(MyStruct m, int i) 
{
    return new MyStruct(m.Number + i);
}


来源:https://stackoverflow.com/questions/14669651/c-sharp-containers-initialized-by-reference-or-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!