web-dev-qa-db-fra.com

Définition du paramètre de type générique sur un type spécifique en C #

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
        }
    }
6
Nipuna

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 {}

Éditer basé sur l'édition de Question

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*/}
}
5
Igor

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.

3
Nikola.Lukovic

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
3
Zein Makki

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.

1
Martin Mulder

Vous pouvez utiliser as pour ce cas

void SomeMethod(T t)
{
    SomeClass obj2 = t as SomeClass;
}
1
Mostafiz

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;
0
Mohammad Ali