I've noticed that C# compiler (.NET 4.5.2) doesn't allow me to compile the following code:
public void Test(out string value)
{
//value = null;
try
{
value = null;
}
catch (Exception ex)
{
//value = null;
}
}
It fails with the following error:
The out parameter 'value' must be assigned to before control leaves the current method
But if I'm uncommenting the assignment in the catch
section, it compiles successfully.
Obviously, it also compiles when I'm uncommenting the assignment before the try
statement.
So the question is why it's insufficient to have the initialization of an out
parameter inside a try block? Why am I forced to do the initialization in the catch
block as well?
The reason is because the out
keyword guarantees that the parameter will be assigned to before the method is exited. As such, if and exception is raised before the value = null;
line executes and there is no assignment to that parameter in the catch block, that guarantee is broken.
If would be the same if you had an if else
statement where one of the two logical blocks did not perform an assignment.
As noted by the MSDN, out
and ref
are similar in that assignments made to this parameter will carry themselves out of the method, but ref
does not make this same guarantee. So if the desired result is a try catch
where there is not an assignment in the catch
block, then perhaps you want the ref
keyword.
Additionally, if this assignment is to be the final line of execution in the try
block, you could logically move it into a finally
block, which guarantees it will execute if an exception is thrown in the try
and, as such, satisfies the requirements of an out
.
You must set the out parameter in your function body. Because code in the try block may or may not execute (since an error could be thrown and control could be transferred to your error handler), you must set the variable somewhere before you leave the function. In the catch
block is a valid place, as is before/after the try { ... } catch{ ... }
, or in the finally { ... }
block
According to C# Sepcification, which says
All output parameters of a function member must be definitely assigned at each location where the
function member returns
(through areturn statement
orthrough execution reaching the end of the function member body
). This ensures that function members do not return undefined values in output parameters, thus enabling the compiler to consider a function member invocation that takes a variable as an output parameter equivalent to an assignment to the variable.
In case of try..catch
the function could return either from Try or from catch. So there are two execution paths so as per the spec compiler does compile time checks if output parameters
has assigned a value in both execution paths.
A solution to your problem would be to assign a default value to the out parameter
. Later you can initialize it in Try
with proper value and compiler won't bother you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With