簡體   English   中英

在C#中通過TypeBuilder創建類型時出現TypeLoadException

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM