为什么使用动态参数调用通用本地函数会产生 BadImageFormatException?
Why does calling a generic local function with a dynamic parameter produce a BadImageFormatException?
尝试使用 C# 7 的本地函数,我得到了一些有趣的行为。考虑以下程序:
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");
这会产生:
Entered Main
... 然后抛出一个 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 得到类似的结果。)
删除代码中指示的行会产生您期望的输出:
Entered Main
Entered DoSomething
Generic
GenericLocal
谁能解释为什么?
当您稍微帮助编译器时,代码不会中断:
GenericLocal<dynamic>((dynamic)obj); // This doesn't break the program
这 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 使编译器在您尝试这样做时产生错误。
CS8322 Cannot pass argument with dynamic type to generic local function 'GenericLocal' with inferred type arguments.
尝试使用 C# 7 的本地函数,我得到了一些有趣的行为。考虑以下程序:
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");
这会产生:
Entered Main
... 然后抛出一个 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 得到类似的结果。)
删除代码中指示的行会产生您期望的输出:
Entered Main
Entered DoSomething
Generic
GenericLocal
谁能解释为什么?
当您稍微帮助编译器时,代码不会中断:
GenericLocal<dynamic>((dynamic)obj); // This doesn't break the program
这 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 使编译器在您尝试这样做时产生错误。
CS8322 Cannot pass argument with dynamic type to generic local function 'GenericLocal' with inferred type arguments.