Laden...

Forenbeiträge von Zoigl Ingesamt 3 Beiträge

14.04.2010 - 08:41 Uhr

den Type und den String will ich dynamisch hinzufügen, deswegen ist es im Beispiel ein String und im anderen Test1 😃

13.04.2010 - 23:40 Uhr

dazu noch der MethodBuilder:


		MethodBuilder methodBuilder =
				typeBuilder.DefineMethod("get_test1", MethodAttributes.Public, typeof(IList), new Type[] {});

Ich will hier die Methode nicht überschreiben, ich generiere meinen eigenen Type 😃

13.04.2010 - 23:37 Uhr

Hi,

ich probiere gerade einen einfach Getter mit IL-code in c# nachzubauen:

	
        public class Test1
	{
		
		public IList test1
		{
			get 
			{
				return Manager.Load(typeof(Test1), "testsa", this);				
			}
		}
	}

	public class Manager
	{
		public static IList Load(Type typeA, string name, object oA) 
		{
			Console.WriteLine("Load(" + typeA + ", " + name + "," + oA + ")");
			return null;
		}
	}

so sieht das ganze nun in C# aus.
Ich möchte aber jetzt die test1-Methode dynamisch mit IL generieren. Natürlich hab ich mir das ganze mit ildasm als IL geholt.
Sieht dann so aus:


		.method public hidebysig specialname instance class [mscorlib]System.Collections.IList  
		        get_test1() cil managed 
		{ 
		  // Code size       27 (0x1b) 
		  .maxstack  3 
		  .locals init ([0] class [mscorlib]System.Collections.IList CS$1$0000) 
		  IL_0000:  nop 
		  IL_0001:  ldtoken    ConsoleApplication1.Test1 
		  IL_0006:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) 
		  IL_000b:  ldstr      "testsa" 
		  IL_0010:  ldarg.0 
		  IL_0011:  call       class [mscorlib]System.Collections.IList Manager::Load(class [mscorlib]System.Type, 
		                                                                              string, 
		                                                                              object) 
		  IL_0016:  stloc.0 
		  IL_0017:  br.s                                                                                           IL_0019 
		  IL_0019:  ldloc.0 
		  IL_001a:  ret 
		} // end of method Test1::get_test1 

Natürlich hab ich das dann in C# nachgebaut:


			ILGenerator ilGenerator = methodBuilder.GetILGenerator();
			Type myType = typeof(String);
			string myString = "testString";
			
			Label endOfMethod = ilGenerator.DefineLabel(); 
			ilGenerator.Emit(OpCodes.Nop);
			ilGenerator.Emit(OpCodes.Ldtoken, myType);
			ilGenerator.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));	
			ilGenerator.Emit(OpCodes.Ldstr, myString);
			ilGenerator.Emit(OpCodes.Ldarg_0);
			ilGenerator.Emit(OpCodes.Call, typeof(Manager).GetMethod("Load", new Type[] {typeof(Type), typeof(string), typeof(object)}));
			ilGenerator.Emit(OpCodes.Stloc_0);
			ilGenerator.Emit(OpCodes.Br_S, endOfMethod);
			ilGenerator.MarkLabel(endOfMethod);
			ilGenerator.Emit(OpCodes.Ldloc_0);
			ilGenerator.Emit(OpCodes.Ret);

Beim Ausführen tritt folgende Exception auf:
System.InvalidProgramException: Invalid IL code in TestType:get_test1 (): IL_0016: stloc.0
Habt ihr eine Idee warum das nicht funktioniert? Bin gerade erst dabei mich in IL einzuarbeiten aber ich versteh nicht warum das nicht geht:/

danke.