Can you please tell me what is the exact use of out
parameter?
Related Question:
What is the differen
Besides allowing you to have multiple return values, another use is to reduce overhead when copying a large value type to a method. When you pass something to a method, a copy of the value of that something is made. If it's a reference type (string for example) then a copy of the reference (the value of a reference type) is made. However, when you copy a value type (a struct
like int
or double
) a copy of the entire thing is made (the value of a value type is the thing itself). Now, a reference is 4 bytes (on 32-bit applications) and an int
is 4 bytes, so the copying is not a problem. However, it's possible to have very large value types and while that's not recommended, it might be needed sometimes. And when you have a value type of say, 64 bytes, the cost of copying it to methods is prohibitive (especially when you use such a large struct
for performance reasons in the first place). When you use out
, no copy of the object is made, you simply refer to the same thing.
public struct BigStruct
{
public int A, B, C, D, E, F, G, H, J, J, K, L, M, N, O, P;
}
SomeMethod(instanceOfBigStruct); // A copy is made of this 64-byte struct.
SomeOtherMethod(out instanceOfBigStruct); // No copy is made
A second use directly in line with this is that, because you don't make a copy of the struct, but refer to the same thing in the method as you do outside of the method, any changes made to the object inside the method, are persisted outside the method. This is already the case in a reference type, but not in value types.
Some examples:
public void ReferenceExample(SomeReferenceType s)
{
s.SomeProperty = "a string"; // The change is persisted to outside of the method
}
public void ValueTypeExample(BigStruct b)
{
b.A = 5; // Has no effect on the original BigStruct that you passed into the method, because b is a copy!
}
public void ValueTypeExampleOut(out BigStruct b)
{
b = new BigStruct();
b.A = 5; // Works, because you refer to the same thing here
}
Now, you may have noticed that inside ValueTypeExampleOut
I made a new
instance of BigStruct
. That is because, if you use out
, you must assign the variable to something before you exit the method.
There is however, another keyword, ref
which is identical except that you are not forced to assign it within the method. However, that also means you can't pass in an unassigned variable, which would make that nice Try.. pattern not compile when used with ref
.
int a;
if(TrySomething(out a)) {}
That works because TrySomething
is forced to assign something to a
.
int a;
if(TrySomething(ref a)) {}
This won't work because a
is unassigned (just declared) and ref
requires that you only use it with an assigned variable.
This works because a
is assigned:
int a = 0;
if(TrySomething(ref a)) {}
However, in both cases (ref
and out
) any changes made to a
within the TrySomething
method are persisted to a
.
As I already said, changes made to a reference type are persisted outside the method in which you make them, because through the reference, you refer to the same thing.
However, this doesn't do anything:
public void Example(SomeReferenceType s)
{
s = null;
}
Here, you just set the copy of a reference to s
to null, which only exists within the scope of the method. It has zero effect on whatever you passed into the method.
If you want to do this, for whatever reason, use this:
public void Example1(ref SomeReferenceType s)
{
s = null; // Sets whatever you passed into the method to null
}
I think this covers all use-cases of out
and ref
.