Difference between passing a reference type and a value type as argument to a method

后端 未结 3 1756
孤城傲影
孤城傲影 2021-01-29 07:34

Just got this confusion running in my mind throughout the day. I am very much confused between reference and value type being passed to a method.

Say I have 2 classes

3条回答
  •  忘掉有多难
    2021-01-29 07:43

    In c#, all arguments sent to method are passing by value, unless they are passed using either the ref or out keywords.

    This includes arguments that are value types, reference types, mutable and immutable types.

    When passing a reference type argument to a method, what actually happens is that the reference of the argument is passed by value.

    This means that the method actually holds a new reference to the argument passed to it.
    So any change to that argument's state will be also reflected when using the reference from outside the method.
    However, when assigning a new value to the reference inside the method, it will not reflect on the reference outside the method.

    For a better, more extensive explanation, read Jon Skeet's Parameter passing in C# article.

    You can't test this using any immutable type, since immutable types, by definition, can't be changed.

    You can, however, test this with any mutable type:

    public static void Main()
    {
        var x = new List();
        x.Add(1);
        Add(x, 2);
        Console.WriteLine(x.Count.ToString()); // will print "2";
        AddRef(ref x, 3);
        Console.WriteLine(x.Count.ToString()); // will print "1";
        Add3(x, 1, 2, 3 );
        Console.WriteLine(x.Count.ToString()); // will also print "1";
        Add3Ref(ref x, 1, 2, 3 );
        Console.WriteLine(x.Count.ToString()); // will print "3";
    }
    
    static void Add(List list, int value)
    {
        // adding an item to the list, thus chaning the state of the list.
        // this will reflect on the list sent to the method, 
        // since a List is a reference type.
        list.Add(value);
    }
    
    static void AddRef(ref List list, int value)
    {
        list = new List(); // same as the s += “Hi”; in the question
        // Adding the value to the list.
        // Note that this change will reflect on the list passed to the method,
        // since it is passed using the ref keyword.
        list.Add(value);
    }
    
    
    static void Add3(List list, int value1, int value2, int value3)
    {
        list = new List(); // same as the s += “Hi”; in the question
    
        // these values are added to the new list.
        // since the reference to the list was passed by value,
        // it WILL NOT effect the list sent to the method.
        list.Add(value1); 
        list.Add(value2);
        list.Add(value3);
    }
    
    static void Add3Ref(ref List list, int value1, int value2, int value3)
    {
        list = new List(); // same as the s += “Hi”; in the question
        // these values are added to the new list.
        // since the list was passed by reference,
        // it WILL effect the list sent to the method.
        list.Add(value1);
        list.Add(value2);
        list.Add(value3);
    }
    

    You can see for yourself on this fiddle.

提交回复
热议问题