为什么使用动态参数调用泛型局部函数会产生BadImageFormatException?

时间:2017-08-03 23:02:33

标签: c# generics dynamic c#-7.0

使用C#7的Local Functions,我最终得到了一些有趣的行为。请考虑以下程序:

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");

这会产生:

  

输入主要

...然后抛出BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)。堆栈跟踪:

   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()

(我在LINQPad中运行它,但是我从dotnetfiddle得到了类似的结果。)

删除代码中的指示行会产生您期望的输出:

  

进入主体   输入DoSomething
  通用
  GenericLocal

任何人都可以解释原因吗?

2 个答案:

答案 0 :(得分:1)

当你帮助编译器时,代码不会破坏:

GenericLocal<dynamic>((dynamic)obj); // This doesn't break the program

答案 1 :(得分:0)

这个turned out to be a bug,但是当dotnet团队研究它时,他们意识到他们无法轻松地解决问题,因此本地通用方法将以非本地通用方法的方式工作。因此,当您尝试执行此操作时,请使用they opted来使编译器产生错误。

CS8322无法将具有动态类型的参数传递给具有推断类型参数的通用本地函数'GenericLocal'。