What's the Difference Between the 'Ref' and 'Out' Keywords

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.

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 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

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 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.

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.

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.


What is the purpose of the ref and out keywords in Vala?

The documentation suggests they are exactly the same as in C#:

  • 'out' from the caller side: you may pass an uninitialised variable to
    the method and you may expect it to be initialised after the method
    returns
  • 'out' from callee side: the parameter is considered uninitialised and
    you have to initialise it
  • 'ref' from caller side: the variable you're
    passing to the method has to be initialised and it may be changed or
    not by the method
  • 'ref' from callee side: the parameter is considered
    initialised and you may change it or not

how ref and out are different at run time?

The difference between ref and out is not in the CLR but in the C# language itself. Ref and Out differs in a way is that the "compiler requires different behaviour" for each of them. Method overloading also isnt allowed at compile time.

As you can see from the code, the only change is address reference specifically this line (if you put value 10, this will up as 10).

IL_0002:  ldc.i4.s   20


Related Topics



Leave a reply



Submit