J'ai une liste d'objets ListOfObjects qui sont tous du même type, mais le type spécifique n'est pas connu (cependant, je connais tous les types possibles). Il y a
de nombreux types possibles. Chaque objet a la propriété Name , qui est une chaîne de son type. Je veux faire quelque chose comme ce qui suit:
switch (ListOfObjects[0].Name)
{
case "Type1":
//cast into Type1 and pass into function
case "Type2":
//cast into Type2 and pass into function
default:
//something
break;
}
Je sais qu'une façon de faire est d'utiliser une instruction switch case
foreach (object elements in ListOfObjects)
{
// Some code here that casts elements into the specific type and pass it into another function
}
Y a-t-il une façon plus propre de faire cela? Est-il possible de stocker les types possibles dans un dictionnaire et de les lancer à partir de ce dictionnaire?
6 Réponses :
Vous pouvez en fait utiliser les propriétés et méthodes système standard pour atteindre votre objectif.
La première chose à faire est d'obtenir le Type:
if (type != null) {
var classInstance = System.ServiceActivator.CreateInstance(type);
// Use the instance here
}
Le paramètre false indique que vous ne souhaitez pas lancer d'exception en cas d'erreur et le paramètre true indique que vous souhaitez ignorer la casse.
Une fois que vous avez un type valide, vous pouvez appeler System .Activator pour créer une nouvelle instance de la classe:
var type = System.Type.GetType(elements.Name, false, true);
Notez que cette surcharge de CreateInstance nécessite un constructeur public sans paramètre. Cependant, il existe d'autres surcharges qui vous permettent de passer des paramètres et d'accéder à des constructeurs non publics.
Vous pouvez utiliser la méthode Type.GetType pour obtenir le type d'objet au lieu de faire une comparaison de chaînes. Voici le même code:
foreach (var element in ListOfObjects)
{
var type = Type.GetType(element.Name);
if (type == typeof(YOUR_OBJECT_TYPE))
{
// Do Something
}
}
En savoir plus sur GetType ici
Si vous avez des surcharges et que vous ne souhaitez pas utiliser un commutateur , vous pouvez utiliser dynamic , mais vous en avez vraiment besoin demandez-vous s'il s'agit d'un problème de conception et qu'il devrait être résolu de manière plus appropriée. C'est-à-dire pourquoi avez-vous quand même besoin de stocker des types non liés dans une liste. href = "https://dotnetfiddle.net/ecU9Zi" rel = "nofollow noreferrer"> Démo complète ici
Remarque : tout cela se cassera s'il ne trouve pas de surcharge. ka-bang! Je ne recommande donc pas de l'utiliser, sauf si vous en avez vraiment vraiment besoin
Je ne sais pas si j'ai bien compris votre question, mais, peut-être que cela peut vous aider, je ne pense pas que vous ayez besoin de garder le type dans le champ du nom puisque vous pouvez obtenir le type comme ça. Et je ne comprends pas non plus pourquoi voulez-vous lancer à nouveau ce type sur lui-même.
foreach (var element in ListOfObjects)
{
var _type = element.getType()
}
et vous pouvez simplement utiliser switch case ou if instructions pour faire route.
p>
Il est certainement possible d'utiliser le mappage de dictionnaire Type et Méthode:
List<Object> collector = new List<Object>(); collector.Add(new Type1()); collector.Add(new Type2()); methodMap[collector[0].GetType()](collector[0]); methodMap[collector[1].GetType()](collector[1]);
Précharger le dictionnaire:
static void Action1(Object obj)
{
//do necessary casting here or not
Console.WriteLine("i handle Type1");
}
static void Action2(Object obj)
{
Console.WriteLine("i handle Type2");
}
Dictionary<Type, Action<Object>> methodMap = new Dictionary<Type, Action<Object>>();
methodMap[typeof(Type1)] = Action1;
methodMap[typeof(Type2)] = Action2;
Et utiliser le dictionnaire: p>
Dictionary<Type, Action<Object>> methodMap = new Dictionary<Type, Action<Object>>();
La carte de méthode type fonctionne également pour les classes dont l'ancienne est différente. ce serait le facteur clé que vous choisiriez pour cette méthode plutôt que pour la surcharge ou la fonction membre virtuelle.
Peut-être pas un doublon exact , mais le même concept: Y a-t-il une meilleure alternative que celle-ci pour activer le type '? Certaines des réponses récentes (mises à jour) traitent du
changementing sur unType.Vous pourriez également être intéressé par les expressions de commutateur C # 8.0 (par opposition aux instructions).
Voir stackoverflow.com/a/299001/41956 . Cela fonctionnerait-il pour vous?
Pourquoi vous ne voulez pas déclarer une méthode abstraite qui est appelée ici et redéfinie par chaque sous-type?