Passing Reference-Type Parameters (C# Programming Guide)

Story of Pass By Value and Pass By Reference in C#

Pass By Value in Reference Types

I have the following class of User which is a reference type as classes are reference types:

public class User
{
    public int UserID {get;set;}
    public string Name {get;set;}
}

We create an instance and set its properties, then we assign it to another instance and change Name property and then we print Name on Console to check what is printed:

User objUser = new User() 
{ 
     UserID = 1, 
     Name = "Ehsan Sajjad" 
};

User objUser2 = objUser;
objUser2.Name = "Jon Doe";

When we create Instance of class User, an object is created in memory(Heap) and memory is allocated to it and we are storing reference to that memory location in objUser reference memory (mostly Stack) so that we can use it further, otherwise it will get lost in the memory so we need to keep a reference to it for doing different operation in memory.

When we assign objUser to objUser2 reference of object memory location which objUser is holding copied to objUser2 , now we have two separate copies of reference but they are both pointing to the same memory location which means they both are referencing the same memory location, so changing the value of Name property will change the value in the object in memory of which we have reference in objUser and objUser, hence "Jon Doe" will be printed on console and it will be reflected in both references.

Diagrammatic/Pictorial Representation of Pass By Value in Reference Types

We can see the same behavior using a method. See the following method to change Name property of User object:

public static void ChangeName(User user)
{
    user.Name = "Jon Doe";
}

We call it to change the object state, it will give the same behavior that we saw in assignment case:

User objUser = new User() { UserID = 1, Name = "Ehsan Sajjad" };

ChangeName(objUser);

Console.WriteLine(objUser.Name);

When we are passing reference objUser of User object to method ChangeName, reference of memory location is copied to the local object user of method, but they are both pointing to the same memory location which means they both are having reference to the same memory location, so changing the value of Name property will change the value in the object in memory of which we have reference in objUser and user, hence "Jon Doe" will be printed on console.

Here is a diagrammatic representation of it:

 When the ChangeName(objUser) is called, as it is referring to the same memory location, it will modify the Name property of User object to "Jon Doe".

But think about what would happen if I set the user to null inside ChangeName method like:

public static void ChangeName(User user)
{
    user = null;
}

and now we call it for objUser:

User objUser = new User() 
{ 
     UserID = 1, 
     Name = "Ehsan Sajjad" 
};

ChangeName(objUser);
Console.WriteLine(objUser.Name);

If you are thinking that it will throw Null Reference Exception, then you are wrong, and if you are thinking that it will output Ehsan Sajjad, then you are right and you have understood that reference is passed by value in C# not by reference.

See the pictorial representation to understand better:

https://www.cnblogs.com/Suanzhai/p/4052545.html

一、引言

  C#中参数的传递方式可以分为两类,按值传递和按引用传递。如果再根据参数的类型进行细分,大致可以分为如下四种:

  • 值类型的按值传递
  • 引用类型的按值传递
  • 值类型的按引用传递
  • 引用类型的按引用传递

  string类型作为一种特殊的引用类型,部分人认为在作为参数进行传递的时候,它的表现与其他的引用类型是不一致的。但是透过现象看本质,我们深入分析一下,就会发现,在作为参数进行传递方面,string类型与其他的引用类型是没有区别的。

Passing Reference-Type Parameters (C# Programming Guide)

https://stackoverflow.com/questions/10792603/how-are-strings-passed-in-net/10792823#10792823

There are two groups of data types in C#: reference types and value types. There are also two ways to pass parameters in C#: by reference and by value. These sound the same and are easily confused. They are NOT the same thing!

If you pass a parameter of ANY type, and you don't use the ref keyword, then you've passed it by value. If you've passed it by value, what you really passed was a copy. But if the parameter was a reference type, then the thing you copied was the reference, not whatever it was pointing at.

A variable of a reference type does not contain its data directly; it contains a reference to its data. When you pass a reference-type parameter by value, it is possible to change the data belonging to the referenced object, such as the value of a class member. However, you cannot change the value of the reference itself; for example, you cannot use the same reference to allocate memory for a new object and have it persist outside the method. To do that, pass the parameter using the ref or out keyword. For simplicity, the following examples use ref.

Passing Reference Types by Value

 class PassingRefByVal
    {
        static void Change(int[] pArray)
        {
            pArray[0] = 888;  // This change affects the original element.
            pArray = new int[5] { -3, -1, -2, -3, -4 };   // This change is local.
            Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
        }

        static void Main()
        {
            int[] arr = { 1, 4, 5 };
            Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr[0]);

            Change(arr);
            Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr[0]);
            Console.ReadLine();
        }
    }
/* Output:
    Inside Main, before calling the method, the first element is: 1
    Inside the method, the first element is: -3
    Inside Main, after calling the method, the first element is: 888
*/

In the preceding example, the array, arr, which is a reference type, is passed to the method without the ref parameter.

In such a case, a copy of the reference, which points to arr, is passed to the method. The output shows that it is possible for the method to change the contents of an array element, in this case from 1 to 888.

However, allocating a new portion of memory by using the new operator inside the Change method makes the variable pArray reference a new array. Thus, any changes after that will not affect the original array, arr, which is created inside Main. In fact, two arrays are created in this example, one inside Main and one inside the Change method.

Passing Reference Types by Reference

The following example is the same as the previous example, except that the ref keyword is added to the method header and call. Any changes that take place in the method affect the original variable in the calling program.

 class PassingRefByRef
    {
        static void Change(ref int[] pArray)
        {
            // Both of the following changes will affect the original variables:
            pArray[0] = 888;
            pArray = new int[5] { -3, -1, -2, -3, -4 };
            Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
        }

        static void Main()
        {
            int[] arr = { 1, 4, 5 };
            Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr[0]);

            Change(ref arr);
            Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr[0]);
            Console.ReadLine();
        }
    }

 All of the changes that take place inside the method affect the original array in Main. In fact, the original array is reallocated using the new operator. Thus, after calling the Change method, any reference to arr points to the five-element array, which is created in the Change method.

A Re-Introduction to C# References Post C# 7

In Summary / Need To Know

  • The ‘value’ in a reference type a memory location where the actual data is
  • Whenever we access a reference type variable, we are fetching the data stored in the memory location it has as its value
  • The default behaviour when we pass it around is that we are copying just this reference value. Changes to the data inside the object are visible by both the original and any copies. Changes to the actual memory location value are not shared between copies of that value.
原文地址:https://www.cnblogs.com/chucklu/p/13153476.html