2016-01-12 20 views
0

我遇到由CreateType方法引發的下劃線異常問題。 異常和第二個問題在最後。在C#中通過TypeBuilder創建類型時出現TypeLoadException#

代碼如下:

定義(工程 - 我希望):

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); 

而現在這裏是代碼不work - overriding 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'。

UPDATE: 我糾正與字符串返回函數上的代碼。現在它幾乎可以工作,但我又收到另一個異常,表明ToString不是虛擬的。

的類型 'System.TypeLoadException' 未處理的異常發生在 mscorlib.dll中

其他信息:方法 '的ToString' 型 '用戶' 從組件MyOwnNewAssembly, 版本= 0.0.0.0,文化= neutral,PublicKeyToken = null'必須是虛擬的才能在接口或超類型中實現該方法。

然後我將方法名稱從「ToString」更改爲「Object.ToString」,但出現相同的異常。

UPDATE 2 我想這是什麼問題。方法構建器應該具有更多的MethodAttributes,如下所示:

  var toStringBuilder = typeBuilder.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig, typeof(string), Type.EmptyTypes); 

感謝您的回答。

+0

您的'ToString'的返回類型似乎丟失 –

+0

@ C.Evenhuis如果您願意,請參閱我的編輯。 – MaLiN2223

回答

2

您的typeBuilder.DefineMethod()調用中的第三個參數應該是typeof(string)而不是null,因爲ToString()返回一個字符串。

該分支很可能是由編譯器爲調試版本引入的。

+0

如果您願意,請參閱我的編輯。 – MaLiN2223

相關問題