Consider the following example:
class Program
{
private static void Main(string[] args)
{
Foo(() => { });
Foo(() => { throw new Exception(); });
Foo(() => { Throws(); });
Foo(() => { throw new Exception(); return; });
Foo(() => { throw new Exception(); return true; });
Console.ReadLine();
}
public static void Foo(Action a)
{
Console.WriteLine("Foo(Action)");
}
public static void Foo(Func<bool> f)
{
Console.WriteLine("Foo(Func<bool>)");
}
public static void Throws()
{
throw new Exception();
}
}
Which has the following output:
Foo(Action)
Foo(Func<bool>)
Foo(Action)
Foo(Action)
Foo(Func<bool>)
I was quite surprised to notice that Foo(() => { throw new Exception(); });
invokes the Foo(Func<bool> f)
overload. I would expect it to invoke the other overload. Also notice that Foo(() => { throw new Exception(); return; });
invokes Foo(Action a)
.
This behavior seems inconsistent. I cannot find the reason for this. It appears that when the compiler detects that the lambda always throws it will favor the Foo(Func<bool> f)
overload, however adding a return statement that never will be reached, will change the behavior. Why does it behave like this?