What are the ref
and out
parameter types of a method in C #? What's the difference between the two? Some examples of use of each.
What are the ref
and out
parameter types of a method in C #? What's the difference between the two? Some examples of use of each.
Simplely a normal parameter has a meaning, it just goes, the value of the argument is only sent to the parameter. The out
also only has one meaning, but otherwise, it only passes the value of the parameter (what is inside the method) to the argument. ref
does both ways. It sends an argument value to the parameter and returns the value of the parameter to the argument .
Both argument and parameter must contain the modifier.
ref
is to pass the argument to reference, that is, instead of passing its value, a pointer is passed that indicates where the value is. This way when the parameter has changed its value, you are changing the argument value since they are in the same memory location.
It only makes sense if the argument has a value. In general the parameter must be changed within the parameter, at least this must happen conditionally.
At the bottom a parameter by reference is a nickname for a variable already existing in another context.
class RefExample {
static void Method(ref int i) {
i = i + 44;
}
static void Main() {
int val = 1;
Method(ref val);
Console.WriteLine(val);
// Output: 45
}
}
out
indicates that the argument to be passed will receive a value inside the method . That is, it is a reference as well, but no value is passed to the parameter, it is just a way of outputting a value. This is usually required because return
can only have a value.
Using the argument does not have to have a value, but the parameter must be given a value before terminating the method.
It is faster in some scenarios.
It's true that you can return a Tuple
. stop "grouping" multiple values. But it is not very elegant. Some however, prefer so.
And the addition of multiple values return in C # 7 is under discussion. You should be able to do this: public (bool, int) Metodo(string)
.
class OutExample {
static void Method(out int i) {
i = 44;
}
static void Main() {
int value;
Method(out value);
// value is now 44
}
}
TryParse()
is one of the best examples of use. It returns an indicated boolean if parse succeeds, and in parameter out
returns the numeric value obtained, if possible. If not possible, nothing is returned in it and can not be used.
In C # 7.2 there is in
% allows a parameter to be received as a reference equal to ref
, however it is guaranteed that this value will not be changed, at least by reference (if you try to modify it will use a COW ). It is useful in cases that require a lot of performance and do not want to allocate in the heap by pressing the GC. Think of it as ref readonly
.
If the language had multiple returns, out
would not be necessary. And ref
would only exist for optimizations, and look, the compiler could probably optimize even without its use. But while that does not happen it's a way to pass data by value as references . The out
mechanism is equal to ref
but the compiler can optimize the code and avoid passing the value.
List
, for example, or any type created with class
), are already passed as ref
(in simplicity, the mechanism of how it is treated is a little different internally).
You should be careful about using ref
in competing scenarios.
If you want a very detailed explanation you have an excellent Jon Skeet article Jon Skeet .
Parameters ref are changed at the calling location. They are passed on as references, not values. This means that you can assign the parameter in the called method and have it also be assigned in the calling location.
The out keyword forces the arguments to be passed by reference. This is like the keyword reference, except that ref requires that the variable be initialized before it is passed. To use a parameter with out, the method definition and the method call must explicitly use the out keyword. For example:
Out
Here are the examples:
static void Main()
{
string value1 = "gato";
SetString1(ref value1); //Passando value1 como referência
Console.WriteLine(value1);
string value2; // String sem atribuição
SetString2(1, out value2); // Passando value2 como out
Console.WriteLine(value2);
}
static void SetString1(ref string value)
{
if (value == "gato")
{
Console.WriteLine("É gato");
}
value = "cachorro"; // Atribui novo valor ao parametro
}
static void SetString2(int number, out string value)
{
if (number == 1)
{
value = "um"; // Atribui o parametro out
}
else
{
value = "outro valor"; // Atribui o parametro out
}
}
Outputs:
It's a cat
puppy
one
References: