Why does calling a generic local function with a dynamic parameter produce a BadImageFormatException?

21

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?

c#
generics
dynamic
c#-7.0

2 Answers

2

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.

answered on Stack Overflow Aug 7, 2020 by StriplingWarrior
1

When you help the compiler a little the code will not break:

GenericLocal<dynamic>((dynamic)obj); // This doesn't break the program
answered on Stack Overflow Sep 14, 2017 by Piet Vredeveld

User contributions licensed under CC BY-SA 3.0