简体   繁体   中英

Passing by reference and using ref

I looked at the similar questions and read some articles. THis article has some pictures which makes it clear.

SomeObject so = new SomeObject();
somefunction(so);
Console.write(so.x); // will print 1

SomeObject so1 = new SomeObject();
somefunctionByRef(so1);
Console.write(so1.x); // will print 1


static void somefunction(SomeObject so)
{
    so.x = 1;
}

public void somefunctionByRef(ref SomeObject so)
{
    so.x = 1;
}

Both of the methods have the same effect on this reference type. so why choose ref keyword for reference types?

is it a bad practice (possibly false) to use somefunction(SomeObject so) and modify the object inside the method and expect the changes without using the ref keyword?

The default parameter passing in .Net is done by value. This is true for both value types and reference types. The difference is that with a reference type you are passing a reference to the instance by value vs. the actual object.

The effect is the so reference in the original function and someFunction are independent. Changing which instance the reference refers to has no affect on the other. However because they refer to the same object they can see mutations to that object done by the other (this is why x changes in your example)

SomeObject so = new SomeObject();
so.x = 42;
somefunction(so);
Console.Write(so.x); // will print 42

static void somefunction(SomeObject so) {
  so = new SomeObject();
  so.x = 13;
}

The ref modifier causes the parameter to be passed by reference instead of value. Effectively there is no copy of the reference, the so in both the original and calling function are the same reference. So resetting one resets the other

SomeObject so = new SomeObject();
so.x = 42;
somefunction(ref so);
Console.Write(so.x); // will print 13

static void somefunction(ref SomeObject so) {
  so = new SomeObject();
  so.x = 13;
}

I only use ref when dealing with non reference types eg int,decimal etc.

take a look at this MSDN page for a bit of a clearer explanation, and for a bit of a gotcha

Classes are already passed by reference (in unmanaged terms so is a pointer to an object). Passing a reference lets you change the underlying variable (you are using a pointer to a pointer). Take this code:

static void foo(SomeObject so)
{
    so.x = 1;
    so = null;
}

static void bar(ref SomeObject so)
{
    so.x = 1;
    so = null;
}

SomeObject so1 = new SomeObject(); 
foo(so1); 
Console.write(so1.x); // will print 1 
bar(so1); 
Console.write(so1.x); // crash

The first method will work and you will print out 1 -- assigning so to null just changes a variable that is local to the function. The second one will cause a crash (NullReferenceException) because so1 has been set to null.

For reference types, by default parameters are passed by reference unless specified to be passed by value. I think this is a safe enough assumption that most .Net dev should know.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM