Laden...

Einfacher Getter mit IL code

Erstellt von Zoigl vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.134 Views
Z
Zoigl Themenstarter:in
3 Beiträge seit 2010
vor 13 Jahren
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.

Z
Zoigl Themenstarter:in
3 Beiträge seit 2010
vor 13 Jahren

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 😃

328 Beiträge seit 2006
vor 13 Jahren

ü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

49.485 Beiträge seit 2005
vor 13 Jahren

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

Z
Zoigl Themenstarter:in
3 Beiträge seit 2010
vor 13 Jahren

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

2.891 Beiträge seit 2004
vor 13 Jahren

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