51 votes

Créer dynamiquement un objet de <Type>

J'ai une table dans ma base de données que j'utilise pour gérer les relations au sein de mon application. c'est assez élémentaire dans la nature - parentType,parentId, childType, childId... tout comme ints. J'ai fait cette configuration avant, mais je l'ai fait avec un switch/case installation lorsque j'avais 6 tables différentes, j'ai été tenté de faire le lien. Maintenant j'ai 30 tables que je suis en train de le faire avec, et je voudrais être en mesure de le faire sans avoir à écrire de 30 cas d'entrées dans mon interrupteur de commande.

Est-il possible que je peux faire référence à un .Net classe à l'aide d'une chaîne de caractères? Je sais que ce n'est pas valide (parce que j'ai essayé plusieurs variantes de ce):

Type t = Type.GetType("WebCore.Models.Page");
object page = new t();

Je sais comment obtenir le Type d'un objet, mais comment puis-je l'utiliser à la volée pour créer un nouvel objet?

67voto

Jason Miesionczek Points 7033

Ce lien devrait aider:

http://msdn.microsoft.com/en-us/library/system.activator.createinstance(VS.71).aspx

Activator.CreateInstance créera une instance du type spécifié.

vous pouvez envelopper cela dans une méthode générique comme celle-ci:

 public T GetInstance<T>(string type)
{
    return (T)Activator.CreateInstance(Type.GetType(type));
}
 

14voto

Judah Himango Points 27365

Si le type est connu de l'appelant, il existe un moyen plus rapide et meilleur que d'utiliser Activator.CreateInstance: vous pouvez utiliser une contrainte générique sur la méthode qui spécifie qu'elle possède un constructeur sans paramètre par défaut.

Le faire de cette manière est digne de confiance et ne nécessite pas de réflexion.

 T CreateType<T>() where T : new()
{
   return new T();
}
 

13voto

AmuuuInjured Points 31
public static T GetInstance<T>(params object[] args)
{
     return (T)Activator.CreateInstance(typeof(T), args);
}

9voto

Andrew Hare Points 159332

Vous voulez utiliser Activator.CreateInstance .

Voici un exemple de la façon dont cela fonctionne:

 using System;
using System.Runtime.Remoting;

class Program
{
    static void Main()
    {
    	ObjectHandle o = Activator.CreateInstance("mscorlib.dll", "System.Int32");

    	Int32 i = (Int32)o.Unwrap();
    }
}
 

1voto

sduplooy Points 3630

En supposant que vous ayez le type suivant:

 public class Counter<T>
{
  public T Value { get; set; }
}
 

et avoir le nom qualifié d'assembly du type, vous pouvez le construire de la manière suivante:

 string typeName = typeof(Counter<>).AssemblyQualifiedName;
Type t = Type.GetType(typeName);

Counter<int> counter = 
  (Counter<int>)Activator.CreateInstance(
    t.MakeGenericType(typeof(int)));

counter.Value++;
Console.WriteLine(counter.Value);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X