views:

53

answers:

4

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?

+1  A: 

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

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

Dylan
+1  A: 

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.

Laurion Burchall
so why choose ref keyword for reference types?
so what is the point you're trying to make?
ronaldwidha
By using `ref`, you can change what object a variable is referring to from a different function. Note the assignment `so = null;`
Jeff M
Classes are not passed by reference, they are in fact not passed at all. Instead references to class instances are passed and they are passed by value.
JaredPar
A: 

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.

ronaldwidha
They're all passed by _value_ by default. The _value_ differs between value types (the object) and reference types (a reference to the object). `ref` and `out` allow passing by reference.
Jeff M
+1  A: 

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;
}
JaredPar