Ok, j'ai mis cette idée toute la journée et j'ai atteint la partie où j'avoue que je ne sais pas. Il est possible que ce que je fais soit juste stupide et qu'il y ait un meilleur moyen, mais c'est là que ma réflexion m'a amené.Comment pouvez-vous convertir un type en utilisant le nom du type en tant que chaîne?
Je tente d'utiliser une méthode générique pour charger des formulaires dans WinForms:
protected void LoadForm<T>(ref T formToShow, bool autoLoaded) where T : FormWithWorker, new()
{
// Do some stuff
}
Les formes sont chargées par un ToolStripMenuItem (soit par la sélection de l'élément ou en utilisant l'option Ouvrir le menu Windows). Ils sont paresseux, donc il y a des champs pour les formulaires dans le parent MDI, mais ils sont nuls jusqu'à ce qu'ils soient nécessaires. J'ai une méthode commune utilisée pour ToolStripMenuItem_Click qui gère tous les clics de l'élément de menu. La méthode n'a aucun moyen de savoir quel formulaire est appelé, sauf que le nom du ToolStripMenuItem correspond à un modèle choisi pour les noms de classe de formulaire auxquels ils correspondent. Ainsi, en utilisant le nom du ToolStripMenuItem, je peux deviner le nom du type de formulaire demandé et le nom du champ privé alloué pour stocker la référence pour ce formulaire. En utilisant cela, je peux soit utiliser une instruction switch croissante/contractante avec des types codés en dur et des chaînes de caractères pour appeler la méthode avec le type spécifique (indésirable), soit utiliser Reflection pour obtenir le champ et créer l'instance du type. Le problème pour moi est, System.Activator.CreateInstance
fournit un ObjectHandler qui ne peut pas être moulé aux types dont j'ai besoin. Voici un extrait de ce que j'ai jusqu'à présent:
string formName = "_form" + ((ToolStripMenuItem)sender).Name.Replace("ToolStripMenuItem", "");
string formType = formName.Substring(1);
FieldInfo fi = this.GetType().GetField(formName, BindingFlags.NonPublic | BindingFlags.Instance);
FormWithWorker formToLoad = (FormWithWorker)fi.GetValue(this);
if (formToLoad == null)
{
formToLoad = (????)System.Activator.CreateInstance("MyAssemblyName", formType);
}
this.LoadForm(ref formToLoad, false);
fi.SetValue(this, formToLoad);
Je connais le nom de chaîne du type qui va dans (????) mais à la compilation, je ne sais pas le type parce qu'il change . J'ai essayé un tas de façons de faire fonctionner cette distribution/instanciation, mais aucune n'a réussi. Je voudrais vraiment savoir s'il est possible d'effectuer une telle distribution en connaissant le type seulement comme une chaîne. J'ai essayé d'utiliser Type.GetType(string, string)
pour effectuer le cast, mais le compilateur n'a pas aimé. Si quelqu'un a une idée différente sur la façon de charger les formulaires dynamiquement parce que je le fais simplement bêtement, s'il vous plaît laissez-moi savoir à ce sujet.
créer un objet FormToLoad et le transformer en FormWithWorker aux points LoadForm et SetValue? – asawyer