我遇到由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);
感謝您的回答。
您的'ToString'的返回類型似乎丟失 –
@ C.Evenhuis如果您願意,請參閱我的編輯。 – MaLiN2223