I am having trouble with understeanding exception thrown by CreateType method. Exception and second question are at the end.
Code looks as follows :
Definitions (works - I hope) :
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);
Constructor creation (works):
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);
And now here is code which doesn't work - overriding ToString:
var method = typeof(object).GetMethod("ToString");
var toStringBuilder = typeBuilder.DefineMethod("ToString", MethodAttributes.Public, null, 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);
and creating type (works):
typeBuilder.CreateType();
builder.Save("Emission.dll");
Here is code wich I am trying to create :
public class User{
private string _name;
public User(string name){
_name = name;
}
public override string ToString(){
return _name;
}
}
After decompilation above ToString looks like :
.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
And my other question is why
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
doesn't looks like this (why there is a jump) :
IL_0007: stloc.0
IL_000a: ldloc.0
Exception is :
An unhandled exception of type 'System.TypeLoadException' occurred in mscorlib.dll
Additional information: Signature of the body and declaration in a method implementation do not match. Typ: 'User'. Assembly: 'MyOwnNewAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Aucun commentaire:
Enregistrer un commentaire