2012-02-23 17 views
6

क्या मैं प्रतिबिंब का उपयोग करके गतिशील रूप से नीचे दिखाए गए वर्ग को बना सकता हूं? कोई विधियां नहीं हैं, केवल सार्वजनिक चर, कुछ में कस्टम विशेषताएं हैं।कक्षा बनाने के लिए प्रतिबिंब का उपयोग करें (एक गतिशील फ़ाइलहेल्पर क्लास बनाने के लिए)

क्या स्वीकृति विधि आवश्यक है (मैंने जो देखा है, "एमिट" थोड़ा चुनौतीपूर्ण दिखता है)।

मैं www.FileHelpers.net से सॉफ़्टवेयर का उपयोग कर रहा हूं, और इसके लिए कक्षा की आवश्यकता है। मेरी सभी फाइल परिभाषा डेटाबेस तालिका में हैं, और मैं सबकुछ अधिक गतिशील बनाना चाहता हूं (यानी फ़ाइल में कोई नया कॉलम दिखाई देने पर कोई कोड नहीं बदलता है)।

[FileHelpers.DelimitedRecord(",")] 
public class FileRow 
{ 
    [FileHelpers.FieldQuoted('"', QuoteMode.OptionalForBoth)] 
    public string Borrower_First_Name; 
    [FileHelpers.FieldQuoted('"', QuoteMode.OptionalForBoth)] 
    public string Borrower_Last_Name; 
    public string Borrower_Email; 
} 

अद्यतन 1: Vlad के जवाब नीचे मैं संदर्भ के लिए DLL की जरूरत के आधार पर, यहाँ है कैसे मैंने किया:

// need to reference the FileHelpers.dll from our own .exe directory 
    string diskFilenameFileHelpersDLL = 
     System.IO.Path.GetDirectoryName(
      System.Reflection.Assembly.GetExecutingAssembly().Location) + 
      @"\FileHelpers.dll"; 

अद्यतन 2: इसके अलावा, क्या Vlad सुझाव दिया करने के बाद, यह कैसे मैं फोन है परिणाम के माध्यम से FileHelper और पाश। मैं शायद डेटा को एक सूची में स्थानांतरित कर दूंगा।

Assembly assembly = compiledResult.CompiledAssembly; 

    // Simple Data Test 
    lineContents = "John,Doe,[email protected]"; 
    FileHelperEngine engine = new FileHelperEngine(assembly.GetType("FileRow")); 
    // FileRow[] FileRowArray = (FileRow[])engine.ReadString(lineContents); 
    Object[] FileRowArray = engine.ReadString(lineContents); 
    Object myObject = FileRowArray[0]; // only 1 row of data in this example 

    // Get the type handle of a specified class. 
    Type myType = assembly.GetType("FileRow"); 
    // Get the fields of the specified class. 
    FieldInfo[] myField = myType.GetFields(); 

    Console.WriteLine("\nDisplaying fields values:\n"); 
    for (int i = 0; i < myField.Length; i++) 
    { 
     Object objTest = myField.GetValue(i); 

     string tempName = myField[i].Name; 
     Object objTempValue = myField[i].GetValue(myObject); 
     string tempValue = System.Convert.ToString(objTempValue); 

     Console.WriteLine("The value of {0} is: {1}", 
          tempName, tempValue); 

    } 
+2

पर एक नजर डालें [हैलो, दुनिया ... Reflection.Emit शैली!] (Http://blogs.msdn.com/b/joelpob/archive/2004/01/21/61411.aspx) –

+0

क्या विशेष रूप से डीएलएल या .EXE बनाते हैं? मुझे सिर्फ स्मृति में कक्षा की आवश्यकता है, डिस्क पर सहेजा नहीं गया है। – NealWalters

+0

मैं कह रहा था कि मुझे डिस्क पर सहेजने की आवश्यकता नहीं है। – NealWalters

उत्तर

2

आप अपने कोड स्ट्रिंग आप एक विधानसभा बनाने के लिए कुछ इस तरह क्या कर सकते हैं के रूप में डेटाबेस में संग्रहीत है:

कारण मैं विशेषताओं पर टिप्पणी की, क्योंकि मैं डॉन ' उनके लिए नामस्थान नहीं है। मुझे लगता है कि आपके पास नेमस्पेस है और आपको इसे संकलित करने के लिए अपने कोड में जोड़ना होगा।

कोड LINQPad में काम करता है, ताकि आप बस कॉपी और पेस्ट कर सकें।

using System; 
using System.Reflection; 
using System.CodeDom.Compiler; 
using Microsoft.CSharp; 

void Main() 
{ 
    StringBuilder dc = new StringBuilder(512); 
    dc.Append("public class FileRow"); 
    dc.Append("{"); 
    //dc.Append("[FileHelpers.FieldQuoted('\"', QuoteMode.OptionalForBoth)]"); 
    dc.Append("public string Borrower_First_Name;"); 
    //dc.Append("[FileHelpers.FieldQuoted('\"', QuoteMode.OptionalForBoth)]"); 
    dc.Append("public string Borrower_Last_Name;"); 
    dc.Append("public string Borrower_Email;"); 
    dc.Append("}"); 

    CompilerResults compiledResult = CompileScript(dc.ToString()); 

    if (compiledResult.Errors.HasErrors) 
    { 
     Console.WriteLine (compiledResult.Errors[0].ErrorText); 
     throw new InvalidOperationException("Invalid Expression syntax"); 
    } 

    Assembly assembly = compiledResult.CompiledAssembly; 

    // This is just for testing purposes. 
    FieldInfo field = assembly.GetType("FileRow").GetField("Borrower_First_Name");   
    Console.WriteLine (field.Name);   
    Console.WriteLine (field.FieldType); 
} 

public static CompilerResults CompileScript(string source) 
{ 
    CompilerParameters parms = new CompilerParameters(); 

    parms.GenerateExecutable = false; 
    parms.GenerateInMemory = true; 
    parms.IncludeDebugInformation = false; 

    CodeDomProvider compiler = CSharpCodeProvider.CreateProvider("CSharp"); 

    return compiler.CompileAssemblyFromSource(parms, source); 
} 
+0

धन्यवाद, मैं जल्द ही कोशिश करूंगा। मुझे इसका उपयोग करने के लिए ऐसा कुछ करने की ज़रूरत है: फ़ाइलरो फ़ाइलरो = ParseFileHelperDataRow (पंक्ति आईडी, रेखा सामग्री, एसक्यूएलकॉन); तो एक बार जब मैं उपरोक्त दिखाता हूं, तो मैं अपनी वस्तु बनाने के लिए प्रतिबिंब का उपयोग करूंगा? – NealWalters

+0

जो मैंने दिखाया है उसके बाद आप अब अपनी असेंबली में ऑब्जेक्ट करेंगे। यदि आप मेरे उदाहरण को देखते हैं तो यह दिखाता है कि आप उस ऑब्जेक्ट पर गुणों को कैसे कॉल कर सकते हैं, लेकिन आप गुण/फ़ील्ड भी निर्दिष्ट कर सकते हैं, उस पर कॉल विधियां। उदाहरण के लिए यदि आपके पास विधि है तो आप उस विधि असेंबली प्राप्त कर सकते हैं। GetType ("FileRow")। GetMethod ("MyMethod); और फिर उस पर कॉल करें। असेंबली वैरिएबल जो आपको मिलता है वह पूरी तरह से आपके कोड को संकलित करता है और आप इसके साथ कुछ भी कर सकते हैं नियमित वस्तुओं/संकलित कोड की तरह। –

+0

इसलिए मुझे उन मानों को निकालने का प्रयास करने से पहले, मेरे ऑब्जेक्ट को मानों के साथ पॉप्युलेट करना होगा; मैं इस तरह कुछ कोशिश करूंगा: ऑब्जेक्ट myObject = assembly.GetType ("FileRow"); myObject = ParseFileHelperDataRow (पंक्ति आईडी, रेखा सामग्री, sqlConn); – NealWalters

2

आप अपनी कक्षा को गतिशील रूप से उत्पन्न करने के लिए कोडडॉम का भी उपयोग कर सकते हैं। अधिक जानकारी के लिए पर जाएँ

http://msdn.microsoft.com/en-us/library/ms404245.aspx

+0

यह आसान लग रहा है; मैंने इसके बारे में भी नहीं सुना है ... यह गुण भी कर सकता है जो मुझे लगता है? – NealWalters

+0

मुझे लगता है कि यह डिस्क पर लिखने के लिए Streamwriter का भी उपयोग कर रहा है। क्या मैं बस क्लास बना सकता हूं और डिस्क पर लिखने के बिना अपने कोड में इसका उपयोग कर सकता हूं? – NealWalters

+0

हां हम CustomAttributes प्रॉपर्टी का उपयोग कर सकते हैं। – Ramesh

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