Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference to reference in C#?

As we all know, C# classes object are treated as references, so what happens when you pass a reference object as a reference to a method? Say we have:

public class A { ... }

and then:

public void F(ref A a) { ... }

Does the compiler find out that a is already a reference type and keep it that way, or he creates a new reference to that object?

And what if we have something like this:

public void F(ref A a)
{
    F(ref a);
}

In this code, besides the obvious StackOverflowException, does the compiler creates reference to reference ... to reference to a which is a reference object?

like image 469
ecampver Avatar asked Mar 10 '13 22:03

ecampver


People also ask

What does by reference mean in C?

Passing by by reference refers to a method of passing the address of an argument in the calling function to a corresponding parameter in the called function. In C, the corresponding parameter in the called function must be declared as a pointer type.

How do you declare a reference variable in C?

References in C++ When a variable is declared as a reference, it becomes an alternative name for an existing variable. A variable can be declared as a reference by putting '&' in the declaration.

Can you pass-by-reference in C?

Pass by Reference A reference parameter "refers" to the original data in the calling function. Thus any changes made to the parameter are ALSO MADE TO THE ORIGINAL variable. Arrays are always pass by reference in C. Any change made to the parameter containing the array will change the value of the original array.

What is call by reference in C with example?

In call by reference, we pass the address of a variable. So, if we modify the value, it will affect the original value of a variable. #include<stdio.h> void print(int *a) { printf("From print function ...\ n"); printf("Address of a = %p\n",a); } int main() { int a = 10; printf("From Main Function ...\


1 Answers

This is best illustrated with an example:

public class C { public int P { get; set; } }
public class X
{
    static void M(C c1, C c2, ref C c3, ref C c4)
    {
      c1.P = 11;
      c2 = new C() { P = 12 };
      c3.P = 13;
      c4 = new C() { P = 14 };
    }
    static void Main()
    {
      C q1 = new C() { P = 1 };
      C q2 = new C() { P = 2 };
      C q3 = new C() { P = 3 };
      C q4 = new C() { P = 4 };
      M(q1, q2, ref q3, ref q4);
      Console.WriteLine(q1.P);
      Console.WriteLine(q2.P);
      Console.WriteLine(q3.P);
      Console.WriteLine(q4.P);
    }
}

What happens?

q1 and c1 refer to the same object but are different variables. Mutating c1.P mutates q1.P because both variables refer to the same object, so q1 is now 11.

q2 and c2 refer to the same object but are different variables. Mutating c2 does not mutate q2 because c2 and q2 are different variables; changing one does not change the other. q2 stays 2, and the new object is lost.

q3 and c3 are two names for the same variable, and therefore refer to the same object. When you change c3.P that changes q3.P automatically because they are two names for the same thing.

q4 and c4 are two names for the same variable, and therefore mutating q4 also mutates c4.

Does that make sense?

It is unfortunate that the keyword for "make an alias to this variable" is "ref". It would have been more clear had it been "alias".

To answer your second question: no, this does not make a chain of references. Let's make a more clear example:

...
int c1 = 123;
M(ref c1);
...
void M1(ref int q1) { M2(ref q1); }
void M2(ref int q2) { M2(ref q2); }

This says that c1 and q1 are different names for the same variable, and q1 and q2 are different names for the same variable, and therefore c1, q1 and q2 are all aliases for each other. There's never a "reference to reference to variable" in C# the way there is in C++.

like image 116
Eric Lippert Avatar answered Oct 23 '22 03:10

Eric Lippert