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 applyInAttribute
andOutAttribute
(or justOutAttribute
) 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 byout
andref
are subtly
different, however they are both very
common. The subtle difference between
these modes leads to some very common
programming errors. These include:
- not assigning a value to an
out
parameter in all control flow paths- not assigning a value to variable
which is used as aref
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
bothref
andout
parameter passing
modes was that allowing the compiler
to detect these common coding errors
was worth the additional complexity of
having bothref
andout
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
Covariance and Contravariance Real World Example
The Foreach Identifier and Closures
What Is the Purpose of the "Prefer 32-Bit" Setting in Visual Studio and How Does It Actually Work
Inconsistent Accessibility: Parameter Type Is Less Accessible Than Method
Mocking Extension Methods With Moq
How to Compile .Net Core App for Linux on a Windows MAChine
Redirecttoaction With Parameter
Reading an Integer from User Input
Enum Tostring With User Friendly Strings
Get String Between Two Strings in a String
Contains()' Workaround Using Linq to Entities
Make an Installation Program For C# Applications and Include .Net Framework Installer into the Setup