Existe-t-il un moyen de créer une instance d'une classe basée sur le fait que je connais le nom de la classe lors de l'exécution. En gros, j'aurais le nom de la classe dans une chaîne.
Existe-t-il un moyen de créer une instance d'une classe basée sur le fait que je connais le nom de la classe lors de l'exécution. En gros, j'aurais le nom de la classe dans une chaîne.
Réponses:
Jetez un œil à la méthode Activator.CreateInstance .
var driver = (OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver", "OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();
C'est assez simple. Supposons que votre nom de classe est Car
et que l'espace de noms est Vehicles
, puis passez le paramètre en tant que Vehicles.Car
qui renvoie l'objet de type Car
. Comme cela, vous pouvez créer n'importe quelle instance de n'importe quelle classe de manière dynamique.
public object GetInstance(string strFullyQualifiedName)
{
Type t = Type.GetType(strFullyQualifiedName);
return Activator.CreateInstance(t);
}
Si votre nom complet (c'est- Vehicles.Car
à- dire dans ce cas) se trouve dans un autre assembly, le Type.GetType
sera nul. Dans de tels cas, vous devez parcourir tous les assemblys et trouver le fichier Type
. Pour cela, vous pouvez utiliser le code ci-dessous
public object GetInstance(string strFullyQualifiedName)
{
Type type = Type.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
{
type = asm.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
}
return null;
}
Maintenant, si vous voulez appeler un constructeur paramétré, procédez comme suit
Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type
au lieu de
Activator.CreateInstance(t);
dynamic
code - voir stackoverflow.com/a/2690661/904521 )
strFullyQualifiedName
avec str
, fullyQualifiedName
fera le travail.
str
- clé est utilisé dans le cadre de la convention de dénomination des variables. Certaines organisations et certains projets insistent pour suivre cela, c'est pourquoi j'ai utilisé. Si vous auriez travaillé dans certaines oraganisations / projets, vous le saurez. Comme vous l'avez dit sans, str
cela fera également l'affaire :) @MehdiDehghani
J'ai utilisé cette méthode avec succès:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
Vous devrez convertir l'objet renvoyé en votre type d'objet souhaité.
Ma question aurait probablement dû être plus précise. Je connais en fait une classe de base pour la chaîne, donc je l'ai résolue par:
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
La classe Activator.CreateInstance a différentes méthodes pour réaliser la même chose de différentes manières. J'aurais pu le lancer sur un objet mais ce qui précède est le plus utile à ma situation.
Je sais que je suis en retard dans le jeu ... mais la solution que vous recherchez pourrait être la combinaison de ce qui précède et l'utilisation d'une interface pour définir vos aspects accessibles au public.
Ensuite, si toutes vos classes qui seraient générées de cette façon implémentent cette interface, vous pouvez simplement transtyper en tant que type d'interface et travailler avec l'objet résultant.
Pour créer une instance d'une classe à partir d'un autre projet dans la solution, vous pouvez obtenir l'assembly indiqué par le nom de n'importe quelle classe (par exemple BaseEntity) et créer une nouvelle instance:
var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
Par exemple, si vous stockez des valeurs de différents types dans un champ de base de données (stocké sous forme de chaîne) et que vous avez un autre champ avec le nom du type (c'est-à-dire String, bool, int, MyClass), alors à partir de ces données de champ, vous pourriez, en théorie, créez une classe de tout type à l'aide du code ci-dessus et remplissez-la avec la valeur du premier champ. Cela dépend bien sûr du type que vous stockez ayant une méthode pour analyser les chaînes dans le type correct. J'ai utilisé cela plusieurs fois pour stocker les paramètres de préférence utilisateur dans une base de données.
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
pourquoi voulez-vous écrire un code comme celui-ci? Si une classe «ReportClass» est disponible, vous pouvez l'instancier directement comme indiqué ci-dessous.
ReportClass report = new ReportClass();
Le code ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
est utilisé lorsque vous n'avez pas la classe nécessaire disponible, mais que vous souhaitez instancier et / ou invoquer une méthode dynamiquement.
Je veux dire qu'il est utile lorsque vous connaissez l'assembly mais en écrivant le code, vous n'avez pas la classe ReportClass
disponible.