Laden...

Einfacher Getter mit IL code

Letzter Beitrag vor 14 Jahren 6 Posts 1.195 Views
Einfacher Getter mit IL code

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.

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 😃

überschreiben kannst du die Methode sowieso nicht, nur mal zur Info (wollte das auch mal machen um mir den Overhead bei INotifyPropertyChanged-Properties zu entfernen .. und hab rausgefunden dass das halt net geht). Wirklich helfen kann ich dir bei deinem problem jetzt auch nicht, bin nicht gerade der Fan von IL.

Aber hier ist eine Seite die mir weitergeholfen hat bei meinen ersten Versuchen http://www.albahari.com/nutshell/ch17.aspx

Was dir auch noch weiterhelfen könnte wäre folgender Link: http://www.codeproject.com/KB/cs/fast_dynamic_properties.aspx

Träume nicht dein Leben sondern lebe deinen Traum.
Viele Grüße, David Teck

Hallo Zoigl,

ich habe mir nicht alles angeschaut, denn schon in der zweiten Emit-Zeile gibt es Unterschiede im Typ (ConsoleApplication1.Test1 vs String). Oder ist das eine absichtliche Abweichung? Du solltest nochmal alles Schritt für Schritt durchgehen.

herbivore

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

Hallo Zoigl,

Bin gerade erst dabei mich in IL einzuarbeiten aber ich versteh nicht warum das nicht geht:/

guck dir mal das Reflector-Addin ReflectionEmitLanguage an.

Gruß,
dN!3L