Ir para o conteúdo
iron

Emit Refleção

Mensagens Recomendadas

iron

Boas. Tenho um trabalho para fazer, só que não estou a perceber o que estou a fazer mal.

Ver se me faço entender de uma maneira fácil.

Tenho de fazer isto mas de modo genérico:

public X
{
  string name;
  int age;
  .
  .
  .
}
public string str(object obj)
{
  X x = (X)obj;
  return "name"+x.GetValue()+"age"+x.GetValue();
}

public interface Serializer
   {
    string ToString(object obj);
   }

private static Serializer CreateSerializer(object obj)
    {
	    AssemblyName aName = new AssemblyName(serialize + obj.GetType().ToString());
	    AssemblyBuilder ab =
		    AppDomain.CurrentDomain.DefineDynamicAssembly(
			    aName,
			    AssemblyBuilderAccess.RunAndSave);
	    ModuleBuilder mb =
		    ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
	    TypeBuilder tb = mb.DefineType(obj.GetType().ToString(), TypeAttributes.Public);
	    //dizer que implementa da interface
	    tb.AddInterfaceImplementation(typeof(Serializer));
	    // criar metodo
	    MethodBuilder meth = tb.DefineMethod(
		    "ToString",
		    MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot,
		    typeof(string),
		    new Type[] { typeof(object) });
	    ILGenerator methIL = meth.GetILGenerator();
	    methIL.Emit(OpCodes.Ldarg_1);
	    methIL.Emit(OpCodes.Castclass, obj.GetType());
	    methIL.Emit(OpCodes.Stloc_0); // local0 = (cast)obj
	    //LocalBuilder str = methIL.DeclareLocal(typeof(String));
	    methIL.Emit(OpCodes.Ldstr, "");
	    methIL.Emit(OpCodes.Stloc_1); //local1 = string
	    PropertyInfo[] fields = obj.GetType().GetProperties(flags).Where(x => !x.Name.Contains("BackingField")).ToArray();
	    foreach (PropertyInfo pInfo in fields)
	    {
		    methIL.Emit(OpCodes.Ldloc_1);
		    methIL.Emit(OpCodes.Ldstr, ToJson(pInfo.Name));
		    methIL.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }, null));
		    methIL.Emit(OpCodes.Stloc_1);
		    methIL.Emit(OpCodes.Ldloc_0);
		    methIL.Emit(OpCodes.Call, pInfo.GetMethod);
		    methIL.Emit(OpCodes.Stloc_2);
		    methIL.Emit(OpCodes.Ldloc_2);
		    methIL.Emit(OpCodes.Call, typeof(JsonfierSerializer).GetMethod("ToJson", new Type[] { typeof(object) }, null));
		    methIL.Emit(OpCodes.Stloc_2);
		    methIL.Emit(OpCodes.Ldloc_1);
		    methIL.Emit(OpCodes.Ldloc_2);
		    methIL.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }, null));
		    methIL.Emit(OpCodes.Stloc_1);
	    }
	    methIL.Emit(OpCodes.Ldloc_1);
	    methIL.Emit(OpCodes.Ret);
	    Type t = tb.CreateType();
	    ab.Save(aName.Name + ".dll");
	    Serializer s = (Serializer)Activator.CreateInstance(t);
	    return s;
}

O erro que dá no ILSpy é este:

ICSharpCode.Decompiler.DecompilerException: Error decompiling System.String Jsonzai.Test.Model.Student::ToString(System.Object)
---> System.ArgumentOutOfRangeException: O argumento especificado estava fora do intervalo de valores válidos.
  em Mono.Collections.Generic.Collection`1.get_Item(Int32 index)
  em ICSharpCode.Decompiler.ILAst.ILCodeUtil.ExpandMacro(ILCode& code, Object& operand, MethodBody methodBody)
  em ICSharpCode.Decompiler.ILAst.ILAstBuilder.StackAnalysis(MethodDefinition methodDef)
  em ICSharpCode.Decompiler.ILAst.ILAstBuilder.Build(MethodDefinition methodDef, Boolean optimize, DecompilerContext context)
  em ICSharpCode.Decompiler.Ast.AstMethodBodyBuilder.CreateMethodBody(IEnumerable`1 parameters)
  em ICSharpCode.Decompiler.Ast.AstMethodBodyBuilder.CreateMethodBody(MethodDefinition methodDef, DecompilerContext context, IEnumerable`1 parameters)
  --- Fim do rastreio da pilha de excepção interna ---
  em ICSharpCode.Decompiler.Ast.AstMethodBodyBuilder.CreateMethodBody(MethodDefinition methodDef, DecompilerContext context, IEnumerable`1 parameters)
  em ICSharpCode.Decompiler.Ast.AstBuilder.CreateMethod(MethodDefinition methodDef)
  em ICSharpCode.Decompiler.Ast.AstBuilder.AddTypeMembers(TypeDeclaration astType, TypeDefinition typeDef)
  em ICSharpCode.Decompiler.Ast.AstBuilder.CreateType(TypeDefinition typeDef)
  em ICSharpCode.Decompiler.Ast.AstBuilder.AddType(TypeDefinition typeDef)
  em ICSharpCode.ILSpy.CSharpLanguage.DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options)
  em ICSharpCode.ILSpy.TextView.DecompilerTextView.DecompileNodes(DecompilationContext context, ITextOutput textOutput)
  em ICSharpCode.ILSpy.TextView.DecompilerTextView.<>c__DisplayClass31_0.<DecompileAsync>b__0()

Desde já obrigado

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.