我在CreateType方法抛出的异常时遇到了问题。例外和第二个问题在结尾。
代码如下:
定义(工作-我希望如此):
AssemblyName name = new AssemblyName("MyOwnNewAssembly");
AssemblyBuilder builder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder moduleBuilder = builder.DefineDynamicModule("Emission", "Emission.dll");
TypeBuilder typeBuilder = moduleBuilder.DefineType("User", TypeAttributes.Public);
typeBuilder.SetParent(typeof(object));
var field = typeBuilder.DefineField("name", typeof(string), FieldAttributes.Private);构造函数创建(作品):
var constructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Any, new Type[] { typeof(String) });
var baseConstructor = typeof(object).GetConstructor(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance, null, new Type[0], null);var genertaor = constructor.GetILGenerator();
genertaor.Emit(OpCodes.Ldarg_0);
genertaor.Emit(OpCodes.Call, baseConstructor);
genertaor.Emit(OpCodes.Nop);
genertaor.Emit(OpCodes.Nop);
genertaor.Emit(OpCodes.Ldarg_0);
genertaor.Emit(OpCodes.Ldarg_1);
genertaor.Emit(OpCodes.Stfld, field);
genertaor.Emit(OpCodes.Ret);下面是不起作用的代码-覆盖ToString:
var method = typeof(object).GetMethod("ToString");
var toStringBuilder = typeBuilder.DefineMethod("ToString", MethodAttributes.Public, typeof(string), Type.EmptyTypes);
typeBuilder.DefineMethodOverride(toStringBuilder, method);
var generator2 = toStringBuilder.GetILGenerator();
generator2.Emit(OpCodes.Nop);
generator2.Emit(OpCodes.Ldarg_0);
generator2.Emit(OpCodes.Ldfld, field);
generator2.Emit(OpCodes.Stloc_0);
generator2.Emit(OpCodes.Ldloc_0);
generator2.Emit(OpCodes.Ret,field);并创建类型(作品):
typeBuilder.CreateType();
builder.Save("Emission.dll");下面是我试图创建的代码:
public class User{
private string _name;
public User(string name){
_name = name;
}
public override string ToString(){
return _name;
}
}在上面的ToString反编译之后,如下所示:
.method public hidebysig virtual
instance string ToString () cil managed
{
.maxstack 1
.locals init (
[0] string
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string AssemblyBuilding.User::_name
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
} // end of method User::ToString我的的另一个问题是为什么
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0看起来不像这样(为什么会有跳转):
IL_0007: stloc.0
IL_000a: ldloc.0例外是:
System.TypeLoadException类型的未处理异常发生在mscorlib.dll中 附加信息:主体签名和方法实现中的声明不匹配。类型:“用户”。程序集:'MyOwnNewAssembly,Version=0.0.0.0,Culture=neutral,PublicKeyToken=null‘。
更新:我用字符串返回函数修正了上面的代码。现在它几乎可以工作了,但是我得到了另一个例外,表明ToString不是虚拟的。
System.TypeLoadException类型的未处理异常发生在mscorlib.dll中 附加信息:来自程序集MyOwnNewAssembly、Version=0.0.0.0、Culture=neutral、PublicKeyToken=null‘的类型为“User”的方法’Version=0.0.0.0‘必须是虚拟的,才能在接口或超级类型中实现该方法。
然后,我将方法名从"ToString“更改为"Object.ToString”,但出现了相同的异常。
更新2我想出了什么问题。方法生成器应该有更多的MethodAttributes,如下所示:
var toStringBuilder = typeBuilder.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig, typeof(string), Type.EmptyTypes);谢谢你的回答。
发布于 2016-01-12 13:00:38
typeBuilder.DefineMethod()调用中的第三个参数应该是typeof(string),而不是null,因为ToString()返回一个字符串。
这个分支很可能是由编译器为调试版本引入的。
https://stackoverflow.com/questions/34743691
复制相似问题