When to Use in VS Ref VS Out

When to use in vs ref vs out

You should use out unless you need ref.

It makes a big difference when the data needs to be marshalled e.g. to another process, which can be costly. So you want to avoid marshalling the initial value when the method doesn't make use of it.

Beyond that, it also shows the reader of the declaration or the call whether the initial value is relevant (and potentially preserved), or thrown away.

As a minor difference, an out parameter needs not be initialized.

Example for out:

string a, b;
person.GetBothNames(out a, out b);

where GetBothNames is a method to retrieve two values atomically, the method won't change behavior whatever a and b are. If the call goes to a server in Hawaii, copying the initial values from here to Hawaii is a waste of bandwidth. A similar snippet using ref:

string a = String.Empty, b = String.Empty;
person.GetBothNames(ref a, ref b);

could confuse readers, because it looks like the initial values of a and b are relevant (though the method name would indicate they are not).

Example for ref:

string name = textbox.Text;
bool didModify = validator.SuggestValidName(ref name);

Here the initial value is relevant to the method.

What's the difference between the 'ref' and 'out' keywords?

ref tells the compiler that the object is initialized before entering the function, while out tells the compiler that the object will be initialized inside the function.

So while ref is two-ways, out is out-only.

Keywords `in, out, ref` vs Attributes `[In], [Out], [In, Out]`

They are not equivalent.

For the ref int[] arr the default [In, Out] attributes will be applied automatically, but it is still not the same as [In, Out] int[] arr.

ref int[] arr is a double indirection (a reference type passed by reference). Use this if the native side is defined something like this: int32_t** arr. This allows to replace not just the elements but the whole array instance as well.

On the other hand, [In, Out] int[] arr is a simple reference passed by value. Use this if the native side also uses single indirection, eg. int32_t* arr. Normally in C# if you pass an array by value (which is a reference type) the called method can replace the elements, which will be reflected from the caller side. However, P/Invoke marshaling works a bit differently:

By default, reference types (classes, arrays, strings, and interfaces) passed by value are marshaled as In parameters for performance reasons. You do not see changes to these types unless you apply InAttribute and OutAttribute (or just OutAttribute) to the method parameter.

So the native side gets a correct pointer regardless of specifying the Out attribute. Specifying [Out] here is needed for the marshaler so it will not omit the copy-back session to the managed memory.

Similarly, in int length will pass a reference to an integer and is not the same as [In] int length, which passes the parameter simply by value. The [In] can be omitted as this is the default marshaling behavior in this case.

Difference between ref and out parameters in .NET

They're pretty much the same - the only difference is that a variable you pass as an out parameter doesn't need to be initialized but passing it as a ref parameter it has to be set to something.

int x;
Foo(out x); // OK

int y;
Foo(ref y); // Error: y should be initialized before calling the method

Ref parameters are for data that might be modified, out parameters are for data that's an additional output for the function (eg int.TryParse) that are already using the return value for something.

What's the difference between ref vs out parameter?

Both a ref parameter and an out parameter make an alias of a variable. That is, when you say:

M(int x) { ... }
...
int y = 123;
M(y);

then the value of y is passed, and x gets a copy of that value.

When you say

N(ref int x) { ... }
...
int y = 123;
N(ref y);

Then x and y are two names for the same variable. A change to x makes a change to y.

The only difference between ref and out from the caller's perspective is that the variable aliased by ref must be definitely assigned before the call. This is legal:

O(out int x) { ... }
...
int y; // no initialization!
O(out y);

But this is not:

N(ref int x) { ... }
...
int y; // no initialization!
N(ref y);

The only differences from the callee's perspective are:

  • a ref parameter can be assumed to be initially assigned; an out parameter cannot.
  • an out parameter must be assigned before control leaves the method normally. That is, this is illegal:

    void O(out int x) { return; }

    x must be assigned before the return.

Behind the scenes, ref and out have the same implementation; the only difference is how the compiler tracks whether variables are assigned or not.

The guidelines for their use are:

  • If you can avoid them, avoid them.
  • If you cannot avoid them, use "out" when you are logically returning a value via modifying the variable and "ref" when you are reading the value of the variable and then possibly modifying the variable. An out must modify, and must not read (before the modification). A ref may modify and can read before modification.

What is diffrence between Out type Vs Ref type parameter in C#?

Both indicate to the caller that the method can modify the value of the parameter. out parameters must be initialized inside the method whereas ref parameters might be initialized outside. It's basically a contract. When you see a method that takes an out parameter this means that that caller can invoke it without initializing the value and be sure that it will be initialized inside:

Foo foo;
SomeMethod(out foo);
// at this stage we know that foo will be initialized

whereas with ref:

Foo foo;
SomeMethod(ref foo); // compile time error

It's the caller's responsibility to initialize the variable before calling the method:

Foo foo = new Foo();
SomeMethod(ref foo); // ok

What is the difference between ref and out?

ref parameters must be initialized before passing to function,the parameter may or may not be changed by the function.So you need to initialize it before you pass, like you do with non-ref arguments:

int i; 
Foo(i); // error unassigned variable
Foo(ref i) // same error

For out, your function guarantees that it will set the argument to a value.So it doesn't need to be initialized.

When should we use ref and out

Here is an example:

    static void Main(string[] args)
{

int i = 1;

foo(i);
Console.Write(i); //i=1;

Reffoo(ref i);
Console.Write(i); //i=2;
}

static void Reffoo(ref int i)
{
i++;
}

static void foo(int i)
{
i++;
}

Why ref and out in C#?

The answer is given in this MSDN article. From that post:

The two parameter passing modes
addressed by out and ref are subtly
different, however they are both very
common. The subtle difference between
these modes leads to some very common
programming errors. These include:

  1. not assigning a value to an out
    parameter in all control flow paths
  2. not assigning a value to variable
    which is used as a ref parameter

Because the C# language assigns
different definite assignment rules to
these different parameter passing
modes, these common coding errors are
caught by the compiler as being
incorrect C# code.

The crux of the decision to include
both ref and out parameter passing
modes was that allowing the compiler
to detect these common coding errors
was worth the additional complexity of
having both ref and out parameter
passing modes in the language.




Related Topics



Leave a reply



Submit