Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why out parameters are required to be initialized inside both try and catch sections?

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?

like image 286
Alexander Abakumov Avatar asked Sep 04 '15 18:09

Alexander Abakumov


Video Answer


3 Answers

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.

like image 156
Will Custode Avatar answered Oct 29 '22 09:10

Will Custode


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

like image 21
Tony Ferrell Avatar answered Oct 29 '22 08:10

Tony Ferrell


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 a return statement or through 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.

like image 26
vendettamit Avatar answered Oct 29 '22 09:10

vendettamit