![](/img/trans.png)
[英]Passing a type generated at RunTime (via TypeBuilder) to GenericClass
[英]TypeLoadException while creating type via TypeBuilder in C#
我遇到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
例外是:
mscorlib.dll中發生了'System.TypeLoadException'類型的未處理異常
附加信息:主體的簽名和方法實現中的聲明不匹配。 類型:“用戶”。 程序集:“ MyOwnNewAssembly,版本= 0.0.0.0,文化=中性,PublicKeyToken =空”。
更新:我糾正了字符串返回函數的上部代碼。 現在它幾乎可以工作了,但是我又收到另一個異常,指示ToString不是虛擬的。
mscorlib.dll中發生了'System.TypeLoadException'類型的未處理異常
附加信息:來自程序集MyOwnNewAssembly,版本= 0.0.0.0,文化=中性,公共密鑰令牌=空的程序集“用戶”中的方法“ ToString”必須是虛擬的,以便在接口或超類型中實現該方法。
然后,我將方法名稱從“ ToString”更改為“ Object.ToString”,但出現了相同的異常。
更新2我知道是什么問題。 方法構建器應具有更多的MethodAttributes,如下所示:
var toStringBuilder = typeBuilder.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig, typeof(string), Type.EmptyTypes);
感謝您的回答。
您的typeBuilder.DefineMethod()
調用中的第三個參數應該是typeof(string)
而不是null
因為ToString()
返回一個字符串。
該分支很可能是由編譯器為調試構建引入的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.