我正在发出一个使用 get 方法显式实现简单接口属性的类。只要接口没有在可移植类库中定义,就没有问题。但是,当将接口移动到 PCL 并仅使用特定类型(如 )时IEnumerable<int>
,PEVerify 将失败。
查看ILDASM -> MetaInfo -> Show,您会看到导入了两个mscorlib
和System.Runtime
程序集引用。这发生在调用DefineMethodOverride
(watch AssemblyBuilder.GetReferencedAssemblies()
to see) 期间。您还可以看到 IEnumerable`1 作为 TypeRef 从两个程序集中引入,这似乎是问题所在。
当不将接口分离到 PCL 时,或者将类型更改为其他类型时,它可以工作并且System.Runtime
不包括引用。要尝试string
,请在界面中替换IEnumerable<int>
withstring
以及DefineProperty
/DefineMethod
调用。
使用MSDN中的修改示例作为重现此问题的简化方法,将下面的代码放入控制台项目中,一切正常。移动interface I
到一个可移植的类库项目,你会明白我的意思。
如何摆脱 PEVerify 错误?
错误:MethodImpl 的 Decl (token=0x0a000001) 和 Body (token=0x00610072) 方法签名不匹配。[令牌:0x19000001] [小时:0x801312F4]
public interface I
{
IEnumerable<int> E { get; }
}
class Test
{
static void Main()
{
string name = "DefineMethodOverrideExample";
AssemblyName asmName = new AssemblyName(name);
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mb = ab.DefineDynamicModule(name, name + ".dll");
TypeBuilder tb = mb.DefineType("C", TypeAttributes.Public);
tb.AddInterfaceImplementation(typeof(I));
PropertyBuilder prop = tb.DefineProperty("I.E", PropertyAttributes.None, typeof(IEnumerable<int>), Type.EmptyTypes);
MethodBuilder mbIM = tb.DefineMethod(
"I.get_E",
MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName,
typeof(IEnumerable<int>),
Type.EmptyTypes);
prop.SetGetMethod(mbIM);
ILGenerator il = mbIM.GetILGenerator();
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Ret);
tb.DefineMethodOverride(mbIM, typeof(I).GetProperty("E").GetGetMethod());
Type tc = tb.CreateType();
ab.Save(name + ".dll");
}
}
(.Net 4.5.1)
(PEVerify 和 ILDASM 版本 4.0.30319.33440 来自 C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\x64)
谢谢!