Playing around with C# 7's Local Functions, I ended up with some interesting behavior. Consider the following program:
public void Main()
{
Console.WriteLine("Entered Main");
DoSomething("");
}
private void DoSomething(object obj)
{
Console.WriteLine("Entered DoSomething");
Generic((dynamic)obj);
GenericLocal(obj);
GenericLocal((dynamic)obj); // This breaks the program
void GenericLocal<T>(T val) => Console.WriteLine("GenericLocal");
}
private void Generic<T>(T val) => Console.WriteLine("Generic");
This produces:
Entered Main
... and then throws a BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
. Stack trace:
at UserQuery.DoSomething(Object obj)
at UserQuery.Main()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
(I'm running this in LINQPad, but I get similar results from dotnetfiddle.)
Removing the indicated line in the code yields the output you'd expect:
Entered Main
Entered DoSomething
Generic
GenericLocal
Can anyone explain why?
This turned out to be a bug, but when the dotnet team looked into it they realized they can't easily fix things so local generic methods would work the way that non-local generic methods would. So instead they opted to make the compiler produce an error when you try to do this.
CS8322 Cannot pass argument with dynamic type to generic local function 'GenericLocal' with inferred type arguments.
When you help the compiler a little the code will not break:
GenericLocal<dynamic>((dynamic)obj); // This doesn't break the program
User contributions licensed under CC BY-SA 3.0