Si vous avez besoin de convertir un paramètre de type générique en un type spécifique, vous pouvez le convertir en un objet et effectuer la conversion comme ci-dessous.
void SomeMethod(T t)
{
SomeClass obj2 = (SomeClass)(object)t;
}
Existe-t-il un meilleur moyen d’y parvenir plutôt que de le lier à un objet puis à un type spécifique?.
Problème
J'ai une fonction générique qui accepte un paramètre de type générique, à l'intérieur de la fonction basée sur une vérification de type, je fais certaines opérations comme ci-dessous
void SomeMethod(T t)
{
if (typeof(T).Equals(typeof(TypeA)))
{
TypeA = (TypeA)(object)t;
//Do some operation
}
else if (typeof(T).Equals(typeof(TypeB)))
{
TypeB = (TypeB)(object)t;
//Do some operation
}
}
Une meilleure conception consiste à y appliquer une contrainte commune au type T et à la classe à laquelle vous voulez vous attendre dans votre méthode, dans ce cas SomeClass
.
class SomeConsumer<T> where T : ISomeClass
{
void SomeMethod(T t)
{
ISomeClass obj2 = (ISomeClass) t;
}
}
interface ISomeClass{}
class SomeClass : ISomeClass {}
C'est mauvais design. Essayez de déplacer cette "opération" dans la classe elle-même afin que l'appelant n'ait pas à connaître le type. Si ce n'est pas possible, partagez davantage de ce qui est fait. Ce que vous voulez faire, c'est que vous n'avez pas une pile d'instructions if/else où l'exécution dépend du type d'objet transmis à la méthode.
class SomeConsumer<T> where T : ISomeClass
{
void SomeMethod(T t)
{
ISomeClass obj2 = (ISomeClass) t;
// execute
t.Operation();
}
}
interface ISomeClass{
void Operation();
}
class SomeClass : ISomeClass {
public void Operation(){/*execute operation*/}
}
Vous pouvez utiliser Convert.ChangeType
SomeClass obj2 = (SomeClass)Convert.ChangeType(t, typeof(SomeClass));
Cependant, gardez à l'esprit que cela lève une exception si un casting est invalide.
Utilisation de as
:
SomeClass obj2 = t as SomeClass;
Cela ne déclencherait pas d'exception et t
serait nul si la conversion échouait.
Je ne sais pas vraiment ce que vous essayez de faire, mais j'espère que vous ne manquez pas le but des génériques ici.
Si votre intention est de restreindre la méthode à SomeClass
et à ses descendants:
void SomeMethod(T t) where T : SomeClass
S'il n'y a pas de relation entre le type d'entrée T
et les types cibles TypeA
ou TypeB
(à l'aide de contraintes de paramètre) et si nous examinons uniquement le problème de conversion, la réponse est simple:
Non, il n'y a pas de meilleur moyen que la méthode que vous utilisez !!!
Je suis d'accord avec d'autres personnes, si vous faites plus d'opérations sur cet objet, vous voudrez peut-être choisir un design différent.
Vous pouvez utiliser as
pour ce cas
void SomeMethod(T t)
{
SomeClass obj2 = t as SomeClass;
}
Je sais que c'est une question tardive mais voici ce que vous pouvez faire
Une bonne option est de faire accepter par votre fonction le paramètre de la classe object
, et de faire le cas de votre choix
Et juste faire le casting
YourClass = (YourClass) parameterObject;