2010-01-07 4 views
3

J'ai une variable chaîne contient:C# créer une instance d'un objet de chaîne

string classCode = "public class Person { public string Name{get;set;} }"; 

Comment puis-je créer une instance d'un objet de la classCode? comme

object obj = CreateAnInstanceAnObject(classCode); 
+0

La personne de classe existe dans votre code, ou voulez-vous à créer. –

+0

La classe de dose de la personne ne sort pas dans le code. – Hamid

Répondre

6

Vous aurez besoin d'utiliser CodeDom pour compiler un ensemble en mémoire, et ensuite utiliser la réflexion pour créer le type.

est ici un sample article on MSDN that walks through the process of code generation.

Une fois que vous avez compilé le code, vous pouvez utiliser Activator.CreateInstance pour créer une instance de celui-ci.

+0

mais je ne veux pas créer une deuxième application en mémoire et je veux créer un objet dans l'application principale – Hamid

+1

Il ne crée pas une deuxième application - il crée un assemblage en mémoire (un peu comme le chargement d'une DLL, mais au lieu de charger à partir du disque, il le génère à la volée). Vous pouvez utiliser Activator.CreateInstance pour créer l'objet en mémoire. –

+0

Est-ce qu'il peut être vidé? (dumping de mémoire) – Hamid

1

mis simple, vous ne pouvez pas faire cela en une ligne que vous essayez. Il est possible de créer une instance d'une classe existante via son nom et l'une des surcharges de Activator.CreateInstance.

Ce que vous essayez d'atteindre ici mais est tout à fait différent. Vous essayez à la fois 1) définir un nouveau type de classe et 2) créer une instance de celui-ci. La définition dynamique de nouvelles métadonnées dans le processus en cours est très difficile à réaliser avec des langages statiques comme C#. Cela nécessite une quantité importante de travail qui ne peut pas facilement être mise dans une réponse StackOverflow.

+0

Pourquoi les gens downvoting cela? Les commentaires de Jared sont tous vrais. Il y a une raison pour laquelle je viens de me connecter aux pages dom du code au lieu d'essayer d'écrire une réponse complète ... –

+0

@Reed, merci! Je ne sais pas non plus :( – JaredPar

+0

Eh bien, mon upvote fait plus que pour les downvotes - mais il est étrange ... (Je souhaite vraiment downvoting obligé un commentaire avec une raison que je déteste ne pas comprendre pourquoi les gens sont downvoting :(..) –

0

Le projet suivant devrait vous guider dans ce que vous essayez d'accomplir:

RunTime Code Compilation

Cependant, si vous essayez d'écrire du code lors de l'exécution, vous voudrez peut-être repenser votre architecture. Vous pouvez créer plus de maux de tête pour vous-même que vous devez être.

Qu'est-ce que vous essayez d'accomplir en créant cet objet?

+0

Je vais concevoir une classe de vérificateur anti-benne et anti-fissure pour mon application, qui doit être créé et fonctionner dynamiquement avec une structure dynamique. – Hamid

3

bâtiment sur le answers de above, voici une démo de travail pour générer, compiler et instancier une classe à partir d'un assemblage en mémoire:

namespace DynamicCompilation 
{ 
    using System; 
    using System.CodeDom; 
    using System.CodeDom.Compiler; 
    using System.Reflection; 

    using Microsoft.CSharp; 

    internal static class Program 
    { 
     private static void Main() 
     { 
      var ccu = new CodeCompileUnit(); 
      var cns = new CodeNamespace("Aesop.Demo"); 

      cns.Imports.Add(new CodeNamespaceImport("System")); 

      var ctd = new CodeTypeDeclaration("Test") 
      { 
       TypeAttributes = TypeAttributes.Public 
      }; 
      var ctre = new CodeTypeReferenceExpression("Console"); 
      var cmie = new CodeMethodInvokeExpression(ctre, "WriteLine", new CodePrimitiveExpression("Hello World!")); 
      var cmm = new CodeMemberMethod 
      { 
       Name = "Hello", 
       Attributes = MemberAttributes.Public 
      }; 

      cmm.Statements.Add(cmie); 
      ctd.Members.Add(cmm); 
      cns.Types.Add(ctd); 
      ccu.Namespaces.Add(cns); 

      var provider = new CSharpCodeProvider(); 
      var parameters = new CompilerParameters 
      { 
       CompilerOptions = "/target:library /optimize", 
       GenerateExecutable = false, 
       GenerateInMemory = true 
      }; 

      ////parameters.ReferencedAssemblies.Add("System.dll"); 

      var results = provider.CompileAssemblyFromDom(parameters, ccu); 

      if (results.Errors.Count == 0) 
      { 
       var t = results.CompiledAssembly.GetType("Aesop.Demo.Test"); 
       var inst = results.CompiledAssembly.CreateInstance("Aesop.Demo.Test"); 
       t.InvokeMember("Hello", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, inst, null); 
      } 

      Console.ReadLine(); 
     } 
    } 
} 
+0

Merci Jesse, votre code source est ce que je recherchais;) – Hamid

+0

De rien, Hamid. N'hésitez pas à voter pour ma réponse et à marquer celle qui a été acceptée. Merci! –

Questions connexes