तो मैं समझता हूँ कि आप क्या चाहते हैं, ऐसा लगता है आप 2 विकल्प हैं:
- use the CodeDOM उत्पन्न करने के लिए और गतिशील, कोड संकलन रनटाइम पर।
- वास्तविक सी # स्रोत कोड उत्सर्जित करें, और गतिशील रूप से इसे रनटाइम पर एक कॉल करने योग्य असेंबली में संकलित करें।
कोडडॉम लिखने के लिए बालों वाले, बहुत कम स्तर के कोड की तरह है। विचार है कि सी # भाषा के लिए एक ऑब्जेक्ट मॉडल है। आप CodeTypeDeclaration को तुरंत चालू करके शुरू करते हैं - इससे एक प्रकार या वर्ग उत्पन्न होगा। फिर आप गुण और फ़ील्ड जोड़ते हैं - यहां आप अपने पी/इनवॉक फ़ंक्शंस के लिए DllImport
घोषणाएं जोड़ देंगे। फिर आप इस प्रकार के विभिन्न कोडडॉम ऐड विधियों का उपयोग करते हैं - यह वह जगह होगी जहां आप जेनरेट की गई विधि डालेंगे। आप इसे सार्वजनिक, स्थैतिक, जो कुछ भी आपको पसंद कर सकते हैं।
CodeDOM इस तरह दिखता है:
System.Type mt= a[0].GetType();
System.CodeDom.CodeTypeDeclaration class1 = new System.CodeDom.CodeTypeDeclaration(mt.Name);
class1.IsClass=true;
class1.TypeAttributes = System.Reflection.TypeAttributes.Public;
class1.Comments.Add(new System.CodeDom.CodeCommentStatement("Wrapper class for " + mt.Name));
System.CodeDom.CodeConstructor ctor;
ctor= new System.CodeDom.CodeConstructor();
ctor.Attributes = System.CodeDom.MemberAttributes.Public;
ctor.Comments.Add(new System.CodeDom.CodeCommentStatement("the null constructor"));
class1.Members.Add(ctor);
ctor.Statements.Add(new System.CodeDom.CodeAssignStatement(new System.CodeDom.CodeVariableReferenceExpression("m_wrapped"), new System.CodeDom.CodeObjectCreateExpression(mt)));
ctor= new System.CodeDom.CodeConstructor();
ctor.Attributes = System.CodeDom.MemberAttributes.Public;
ctor.Comments.Add(new System.CodeDom.CodeCommentStatement("the 'copy' constructor"));
class1.Members.Add(ctor);
ctor.Parameters.Add(new System.CodeDom.CodeParameterDeclarationExpression(mt,"X"));
ctor.Statements.Add(new System.CodeDom.CodeAssignStatement(new System.CodeDom.CodeVariableReferenceExpression("m_wrapped"), new System.CodeDom.CodeVariableReferenceExpression("X")));
// embed a local (private) copy of the wrapped type
System.CodeDom.CodeMemberField field1;
field1= new System.CodeDom.CodeMemberField();
field1.Attributes = System.CodeDom.MemberAttributes.Private;
field1.Name= "m_wrapped";
field1.Type=new System.CodeDom.CodeTypeReference(mt);
class1.Members.Add(field1);
...
उस पर चला जाता है। और इसपर। जैसा कि आप देख सकते हैं, यह बहुत बदसूरत हो जाता है।फिर बाद में आप इसे संकलित करते हैं, जिसे मैंने नहीं दिखाया। मुझे लगता है कि आप इस दृष्टिकोण को नहीं लेना चाहते हैं।
मुझे कोडडॉम का उपयोग करने के लिए बहुत क्रूरता मिली; इसके बजाय, अब जब मुझे गतिशील रूप से जेनरेट की गई असेंबली की आवश्यकता होती है, तो मैं वास्तविक सी # कोड उत्सर्जित करता हूं, आमतौर पर टेम्पलेट्स के माध्यम से, स्मृति में एक स्ट्रिंग में, और संकलित करता हूं। यह मेरे उद्देश्यों के लिए बहुत आसान है। संकलन इस तरह दिखता है:
var cp = new System.CodeDom.Compiler.CompilerParameters {
ReferencedAssemblies.Add(filesystemLocation), // like /R: option on csc.exe
GenerateInMemory = true, // you will get a System.Reflection.Assembly back
GenerateExecutable = false, // Dll
IncludeDebugInformation = false,
CompilerOptions = ""
};
var csharp = new Microsoft.CSharp.CSharpCodeProvider();
// this actually runs csc.exe:
System.CodeDom.Compiler.CompilerResults cr =
csharp.CompileAssemblyFromSource(cp, LiteralSource);
// cr.Output contains the output from the command
if (cr.Errors.Count != 0)
{
// handle errors
}
System.Reflection.Assembly a = cr.CompiledAssembly;
// party on the type here, either via reflection...
System.Type t = a.GetType("TheDynamicallyGeneratedType");
// or via a wellknown interface
उपरोक्त कोड में, LiteralSource
स्रोत कोड संकलित की हैं। जैसा कि मैंने कहा, मैं इसे एक टेम्पलेट पढ़ने और रिक्त स्थान भरकर उत्पन्न करता हूं।
यह एक दिलचस्प दृष्टिकोण है, मैंने कभी भी वास्तविक सी # लिखने के बारे में सोचा नहीं था। शायद मैं क्या करूँगा। धन्यवाद। – jsimmons
आप डिस्क पर कक्षाओं को पहली जगह कैसे बनाते हैं? – jcolebrand
@jcolebrand - मैं स्पष्ट नहीं हूं कि आप क्या पूछ रहे हैं, लेकिन मुझे लगता है कि आपको एक नया प्रश्न पोस्ट करना चाहिए। – Cheeso