I stumbled across something odd: I got a BadImageFormatException
without knowing what image (assembly) it could possibly refer to.
I reduced the solution so that it consists only of a single project with no dependencies:
As you can see, it only uses System
(and mscorlib
), and of course I don't load assemblies at run time.
It compiles as AnyCpu with .NET 4.5.2, VS 2015 with C#6, although none of this should really matter.
I tried to make a sample with C#5, but once I replace all the "?." operators, it stops happening.
I have hosted the project so that people can try it themselves:
git clone -b crash-sample https://github.com/jtheisen/moldinium.git
I clean-built and tested it on 4 machines, all showing the same effect.
The stack trace of the crash is:
Ex.: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
at IronStone.Moldinium.LiveList.<>c__DisplayClass10_0`1.<Where>b__2(ListEvent`1 v)
at IronStone.Moldinium.ActionObserver`1.OnNext(T value) in C:\Source\Repos\moldinium\ConsoleApplication1\Rx.cs:line 51
...snipped...
Running PEVerify on the output produces the following error:
[IL]: Error: [C:\Source\Repos\moldinium\ConsoleApplication1\bin\Debug\Bad.exe : IronStone.Moldinium.LiveList+<>c__DisplayClass10_0`1[TSource]::b__2][offset 0x0000013B] Unable to resolve token.
Removing all the ?.
operators from the Select.cs file resolves the issue.
Using ILSpy I have isolated the problem to:
IronStone.Moldinium.LiveList.<>c__DisplayClass10_0`1.<Where>b__2
You can see the IL Dumps of the method (via ILSpy) in a gist here. The Bad IL is when using ?.
the Good IL is C# 5.0 style.
This has been build with VS2015.3
CSC Version: Microsoft (R) Visual C# Compiler version 1.3.1.60616
答案 0 :(得分:3)
我无法帮助你,因为它确实是一个错误。但是我可以把你带到发生错误的地方,它可以帮助你在几行代码中重现这个错误。
namespace ElvisBugInNullableGenericStructWithNestedTypeParameter
{
struct MyGenericStruct<T> { }
class Program
{
static void Main() { }
void Test<T>()
{
Func<T, bool> func = (arg =>
{
MyGenericStruct<T>? v1 = null;
return v1?.ToString() == null;
});
}
}
}
如果我将MyGenericStruct<T>?
替换为MyGenericStruct<int>?
,它将有效。
问题是,出于某种原因,当我们在可空结构中使用外部T
然后我们尝试使用Elvis运算符?
时,类型是未知的(无法解析令牌)。
<强>更新强>
如果您想修复案例,则无需删除所有Elvis操作符,只需将其从Subscribe
方法中的public static ILiveList<TSource> Where<TSource>(this ILiveList<TSource> source, Func<TSource, Boolean> predicate)
操作中删除即可。