tags:

views:

269

answers:

6

Duplicate of: What is the purpose of the “out” keyword at the caller?

Why I need to use 'ref' keyword in both declaration and Call.

void foo(ref int i)
{

}

For example, Consider above function. If I will call it without ref keyword as

foo(k);

it will give me error :

Argument '1' must be passed with the 'ref' keyword

Why isn't it enough to just specify in the method signature only ?

+5  A: 

This is because ref indicates that the parameter should be passed in by reference. It is something like pointer in C++

For example;

void CalFoo()
{
  var i=10;
  foo(ref i);  //i=11
}
void foo(ref int i)
{
   i++;
}

but

void CalFoo()
{
  var i=10;
  foo(i);  //i=10
}
void foo(int i)
{
   i++;
}

I think you can have both foo(ref int) and foo(int) in one single class. So if you don't specify the ref.. how does the compiler knows which one to call?

Ngu Soon Hui
@Ngu Soon Hui : Ya I agree with that. But my question is why I need to use it in both Method call and declaration.
Mahin
Ngu Soon Hui : Great thanks.. Now I understand why.. Will wait for few more answers... otherwise you rock.... +1
Mahin
Because they `int` and `ref int` are different types, also for overloading. See the last sentence in this answer. If you would allow dropping the `ref` then your method call would have a different signature than the invoked method. Surely solvable, unless overloading strikes. But it could lead to all sorts of subtle bugs. Also you know explicitly that the method *can change* the object reference when calling methods with `ref`.
Joey
I wouldn't bring up the overloading issue at all for this question... The compiler for .NET does some very complex overloading resolving behind the scenes (especially now with the introduction of the `dynamic` type) and has errors for ambiguous cases. What's much more important with using the `ref` keyword is to explicitly show that the value might change in the method call.
Blixt
@Johannes: They are not different types, you can't overload a method with only a ref or 'normal' type: http://msdn.microsoft.com/en-us/library/14akc2c7(VS.80).aspx , second code sample
Lennaert
No, you cannot have both in one class. Overloads which differ only by ref/out are not allowed. That's because int and ref int is in fact the same type, just using a different parameter passing convention.
Maximilian Mayerl
You can have signatures `int` and `ref int` or `int` and `out int`, but you cannot have signatures `ref int` and `out int`.
Blixt
+5  A: 

It enhances readability/understandability: When you look at the method call, you know that the ref value might change.

Lennaert
@Lennaert : Sounds like a valid argument. Can you point me to some manual stating this, if you have?
Mahin
Actually, I can't find anything about it, but the compiler is smart enough to infer that it should pass a ref type (I assume), that's how I came to the conclusion. Maybe I stated it a bit too confidently :)
Lennaert
+2  A: 

As the Method and the Caller may be "far" away from each other (Different Assemblies, you may not even have the source of the one containing the method), having to specify out and ref explicitly helps making the intent clear. So it's something for the user so that they really know what they do, not a technical necessity.

Michael Stum
+2  A: 

While ref could most of the time be inferred from the method signature, it's always obligatory due to the fact that it can change the behavior of the code after the method call completely. Consider:

string hello = "world";
MyMethod(ref hello);
Console.WriteLine(hello);

If the ref keyword hadn't been there you would always expect the code to print out "world", while in reality, it can print anything.

Blixt
+3  A: 

(As mentioned, this is a dupe of this question.)

For one thing, it's used as part of method overloading:

public void Foo(string x) { ... }
public void Foo(ref string x) { ... }

...

string x = "";
Foo(x); // Which should be used if you didn't have to specify ref?

Now one answer could be to prohibit that sort of overloading... but I think it's a good thing for C# to require this at the caller's side as documentation:

  • The behaviour changes significantly when you use ref (or out)
  • By calling out the rare uses of ref/out, it means you never need to check whether the argument is being passed by value or reference
  • It also affects what you can pass (e.g. you can't pass a literal, or the result of a method call). This is clearer when it's explicit.

Note that C# 4 does allow implicit use of ref for COM methods as there are so many ref parameters which don't really have ref behaviour (or at least, they don't take advantage of it). In such cases the compiler introduces a new local variable so that from the caller's point of view the argument really is being passed by value:

ComMethod(x);

translates into:

MyType tmp = x;
ComMethod (ref tmp);

This is a good compromise for COM methods, but I'm glad it's not the case for normal managed code.

Jon Skeet
You are right Jon.. It is duplicate of http://stackoverflow.com/questions/1393946/what-is-the-purpose-of-the-out-keyword-at-the-caller-in-c/1393956#1393956.I have also voted to close it. Btw , You have also answered that question. Thanks.
Mahin
@Jon : Btw, I had this question after reading your this ( http://www.yoda.arachsys.com/csharp/parameters.html ) article.
Mahin
@Mahin: Good feedback - if I remember, I'll try to add a section to that article.
Jon Skeet
A: 

I have also heard (or read somewhere - myaybe it was in an interview with the language designers) that the reason (like for many other "features" in C#) is to remind the programmer that the function he is giong to call use the argument by reference.

gius