0

Possible Duplicate:
When to pass ref keyword in

Hi All,

I am just surprised that why we have ref in C# while by default everything which is a reference type in C# is passed as a reference.

In simpler words, can anyone explain me the difference between these two method calls:

public void Test(SomeClass someClass)
{
  // some code here
} 

and

public void Test(ref SomeClass someClass)
{
  // some code here
}

In my thinking they both have reference to same memory location.

So why do we need ref keyword at all ?

Community
  • 1
  • 1
Embedd_0913
  • 16,125
  • 37
  • 97
  • 135

5 Answers5

8

The ref keyword passes in a reference to whatever location is storing the reference. This allows you to manipulate this variable from the called function. This is particularly useful for value types, but also has uses when used with reference types. (Dictionary.TryGetValue() being a good example. The out parameter is required to return the value stored in the dictionary. out is equivalent to ref except that it will undergo a different set of compile-time checks.)

For example:

public void Test(ref SomeClass obj)
{
    obj = null;
}

public void Test2(SomeClass obj)
{
    obj = null;
}

public void Foo()
{
    SomeClass obj = new SomeClass();
    Test(ref obj);
    // obj is null here!

    obj = new SomeClass();
    Test2(obj);
    // obj is not null here.
}
cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • After calling test2, obj would indeed be null – Chandu Dec 21 '10 at 21:00
  • 4
    @Cybernate: No, it wouldn't. Compile and test for yourself. The `obj = null` line in `Test2` will only set the parameter variable to null; it will not affect the `obj` local in `Foo`. – cdhowie Dec 21 '10 at 21:01
  • My bad... You are right. Learnt a new thing today :). Adding my vote to the answer... – Chandu Dec 21 '10 at 21:05
  • @Cybernate, calling Test2 would not nullify obj. Passing obj without a ref gets its own stack in the heap, if you don't believe me try it out. Edit: Didn't refresh so I wasn't aware your comment already was answered. – Gary L Cox Jr Dec 21 '10 at 21:08
  • @Gary: I tried and realized that obj = null will set the local reference variable to point to null and not the original memory allocation – Chandu Dec 21 '10 at 21:10
3

I am just surprised that why we have ref in C# while by default everything is which is a reference type in C# is passed as a reference.

Because some things in C# are value types, and sometimes we want to pass those. We have the ref keyword so that those things can be passed by reference also.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
3

It's analogous to the difference between a SomeClass * and a SomeClass ** in C++.

With a SomeClass * (or without ref), we can modify the object pointed to, but we can't redirect it to an entirely new object.

With a SomeClass ** (or with ref), we can change the argument in the calling code in order to point it to an object of our choosing.

Anon.
  • 58,739
  • 8
  • 81
  • 86
2

When you pass an object you pass it by reference. This means that anything you do to that object will be reflected in the object after the method returns. When you pass the reference by reference i.e. void Foo(ref object obj) you are passing the address of that object. You can then re-assign the address to a different object and that will be the state of things when the method returns

foo (object o)
{
   ...
}

var v = new object();
foo(v);

v will still reference the same object that was instantiated prior to the call to foo

void bar(ref object o)
{
   o = null;
}

var v = new object();
foo(ref v);
// v is now null
SwDevMan81
  • 48,814
  • 22
  • 151
  • 184
beezler
  • 646
  • 6
  • 18
  • 1
    *"When you pass the reference by reference i.e. `void Foo(ref object obj)` you are passing the address of that object."* No, you pass the address of the reference to the object. Passing the address of the object is what happens without `ref`. – cdhowie Dec 21 '10 at 22:31
0

Suppose method Foo accepts a Bar by value. If I have a Bar called "Boz", the statement:

  Foo(Boz);

may take the object pointed to by Boz and change that object's characteristics, but it cannot change which object Boz points to. By contrast, if Boz were passed by reference, the same statement could cause Boz to point to a different object entirely.

As an example of usage, consider a routine that accepts an array as a parameter. If an array is passed by value, the recipient can change the value of any of the items in the array, but the recipient cannot change the size. The only way to change the size of an array is to create a new array, copy the old items into it, and from thence forth use the new array instead of the old one. When an array passed by value, there is no way for the recipient to tell the caller that it should stop using the old array and use the new one instead. With an array passed by reference that is not a problem.

supercat
  • 77,689
  • 9
  • 166
  • 211