Why is my finally block not working in C #?

I helped my colleague debug some strange behavior in my code. The following example illustrates this:

static void Main(string[] args) { string answer = Sample(); Console.WriteLine(answer); } public static string Sample() { string returnValue = "abc"; try { return returnValue; } catch (Exception) { throw; } finally { returnValue = "def"; } } 

What returns this sample?

You think that because of the finally block it returns "def", but actually it returns "abc"? I went through the code and confirmed that the finally block was actually called.

The real answer is that you shouldn't write such code in the first place, but I'm still puzzled by the behavior.

Edit: Refine the stream based on some answers.

When you step through the code, ending is done before returning.

Duplicate: What really happens in try {return x; } finally {x = null; }?

+6
c # finally
source share
7 answers

Yes, the finally block is started after the function returns, but it does not matter. Remember that the return value is passed by value, so a new temporary variable is created to return it to the temporary structure, so the finally block does not affect the actual return value. If you want to support the desired behavior, you can use the out parameter, for example:

 static void Main(string[] args) { string answer; Sample(out answer); Console.WriteLine(answer); } public static void Sample(out string answer) { try { answer = "abc"; return; } catch (Exception) { throw; } finally { answer = "def"; } } 

Or you can simply move the return statement outside of the try block, for example:

 static void Main(string[] args) { string answer = Sample(); Console.WriteLine(answer); } public static string Sample() { string returnValue; try { returnValue = "abc"; } catch (Exception) { throw; } finally { returnValue = "def"; } return returnValue; } 

However, given that the finally block will always override the return value, this is a dubious design.

+3
source share

Your finally block assigns a value to returnValue and does not actually return a value. The "return" has already occurred before the finally block changes the value and, therefore, "abc" is returned.

So far, the code is confusing, because what you did does not make sense that it is doing it right.

+12
source share

The finally block works efficiently after the return . That way, you already returned the old abc value before going to your finally block.

(this is not quite the way it works under the hood, but it is close enough for the point here)

+3
source share

Found this link some time ago, which relates to this particular issue. He tries to show the IL code that leads home exactly what is happening.

+2
source share

I am not an expert, but I would have to assume that this function will return, and then it will finally call. Since return returnValue has already been completed, it really doesn't matter what value returnValue takes in the finally block. This behavior makes sense because it is assumed that the entire try block will run before the finally block, and the only way it can do it is to return it from the function as intended.

0
source share

If you are really interested in knowing what is happening, you can download and install Reflector . This is a fantastic tool that can be put in a "bag of tricks." He will tell you what is happening under the hood.

0
source share

I guess I would say that you determine what will be returned (reference to the string "abc") at the point where the return statement is.

Thus, the fact that, finally, later establishes that the link to the link to another line does not affect the return value.

0
source share

All Articles