2009-10-20 12 views
5

मैं कोड उत्पन्न करने की कोशिश कर रहा हूं जो स्ट्रिंगबिल्डर लेता है, और एक वर्ग में सभी गुणों के मूल्यों को स्ट्रिंग में लिखता है। मैं निम्नलिखित मिल गया है, लेकिन मैं वर्तमान में एक "अवैध विधि टोकन" निम्नलिखित कोड में हो रही है:सीआईएल में स्ट्रिंगबिल्डर (एमएसआईएल)

public static DynamicAccessor<T> CreateWriter(T target) //Target class to *serialize* 
    { 
     DynamicAccessor<T> dynAccessor = new DynamicAccessor<T>(); 

     MethodInfo AppendMethod = typeof(StringBuilder).GetMethod("Append", new[] { typeof(Object) }); //Append method of Stringbuilder 

     var method = new DynamicMethod("ClassWriter", typeof(StringBuilder), new[] { typeof(T) }, typeof(T), true); 
     var generator = method.GetILGenerator(); 
     LocalBuilder sb = generator.DeclareLocal(typeof(StringBuilder)); //sb pointer 


     generator.Emit(OpCodes.Newobj, typeof(StringBuilder)); //make our string builder 
     generator.Emit(OpCodes.Stloc, sb);      //make a pointer to our new sb 


     //iterate through all the instance of T's props and sb.Append their values. 
     PropertyInfo[] props = typeof(T).GetProperties(); 
     foreach (var info in props) 
     { 
      generator.Emit(OpCodes.Callvirt, info.GetGetMethod()); //call the Getter 
      generator.Emit(OpCodes.Ldloc, sb);      //load the sb pointer 
      generator.Emit(OpCodes.Callvirt, AppendMethod);  //Call Append 
     } 

     generator.Emit(OpCodes.Ldloc, sb); 
     generator.Emit(OpCodes.Ret);   //return pointer to sb 

     dynAccessor.WriteHandler = method.CreateDelegate(typeof(Write)) as Write; 
     return dynAccessor; 
    } 

कोई भी विचार? अग्रिम धन्यवाद :)

+0

:

DynamicAccessor<T> dynAccessor = new DynamicAccessor<T>(); MethodInfo AppendMethod = typeof(StringBuilder).GetMethod("Append", new[] { typeof(Object) }); //Append method of Stringbuilder var method = new DynamicMethod("ClassWriter", typeof(StringBuilder), new[] { typeof(T) }, typeof(T), true); var generator = method.GetILGenerator(); generator.Emit(OpCodes.Newobj, typeof(StringBuilder).GetConstructor(Type.EmptyTypes)); //make our string builder //iterate through all the instance of T's props and sb.Append their values. PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var info in props) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Callvirt, info.GetGetMethod()); //call the Getter if (info.PropertyType.IsValueType) { generator.Emit(OpCodes.Box, info.PropertyType); } generator.Emit(OpCodes.Callvirt, AppendMethod); //Call Append } generator.Emit(OpCodes.Ret); //return pointer to sb 

इस के बराबर उत्पन्न करता है टिप्पणी करने के लिए) –

उत्तर

5

कोई भी गुण जो मूल्य-प्रकार (int आदि) मुक्केबाजी की आवश्यकता होगी; या आपको एक अलग Append ओवरलोड का उपयोग करने की आवश्यकता होगी।

इसके अलावा

:

  • आप वस्तु हर बार (arg0)
  • StringBuilder.Append एक धाराप्रवाह एपीआई है लोड करने के लिए की जरूरत है; एक परिणाम के रूप
  • , आप क्षेत्र की जरूरत नहीं है

(व्यक्तिगत रूप से, हालांकि, मैं एक string वापसी चाहते हैं, लेकिन "हुंह": आप या तो मूल्य पॉप, या करने की जरूरत है उसका फिर से उपयोग)

तो जैसा: (उत्तर दिया

StringBuilder ClassWriter(T obj) { 
    return new StringBuilder.Append((object)obj.Foo).Append((object)obj.Bar) 
        .Append((object)obj.Blip).Append((object)obj.Blap); 
} 
+0

+1, बहुत अच्छी तरह से समझाया गया। –

+0

आह धन्यवाद, यह एक सुपर स्पष्टीकरण है! मैं देखता हूं कि मुक्केबाजी से आपका क्या मतलब है, मैं संकलक के लिए सही ओवरलोड को स्वचालित रूप से हल करने के लिए इतना उपयोग कर रहा हूं। मुझे यकीन नहीं है कि एपेंड द्वारा आपका क्या मतलब है एक धाराप्रवाह एपीआई है, क्या इसका मतलब यह है कि जो मूल्य जोड़ा जा रहा है उसे ढेर से नहीं लिया जा रहा है? और Ldarg_0 कहां से इनपुट प्राप्त करता है? सभी प्रश्नों के लिए क्षमा करें xD – Josh

+2

धाराप्रवाह से, मेरा मतलब है कि परिशिष्ट 'शून्य 'वापस नहीं करता है - यह' यह 'देता है; आप 'एपेंड (...) को कॉल करें। (...)। संलग्न करें (...) 'आदि। आप प्रत्येक कॉल के बाद स्टैक पर एक मूल्य छोड़ रहे थे। 'arg0' इनपुट पैरामीटर है (क्योंकि यह एक स्थिर विधि है)। एक उदाहरण विधि के लिए, 'arg0' "यह" है। –

संबंधित मुद्दे