web-dev-qa-db-fra.com

La valeur de type 'T' ne peut pas être convertie en

Ceci est probablement une question de novice, mais Google n'a étonnamment pas fourni de réponse.

J'ai cette méthode plutôt artificielle

T HowToCast<T>(T t)
{
    if (typeof(T) == typeof(string))
    {
        T newT1 = "some text";
        T newT2 = (string)t;
    }

    return t;
}

Venant d'un contexte C++, je m'attendais à ce que cela fonctionne. Toutefois, la compilation échoue avec "Impossible de convertir implicitement le type 'T' en chaîne" et "Impossible de convertir le type 'T' en chaîne" pour les deux affectations ci-dessus.

Je suis soit en train de faire quelque chose de faux conceptuellement, soit tout simplement de ne pas avoir la bonne syntaxe. S'il vous plaît aidez-moi à trier celui-ci.

Je vous remercie!

129
Alex

Même s'il se trouve à l'intérieur d'un bloc if, le compilateur ne sait pas que T est string.
Par conséquent, il ne vous permet pas de lancer. (Pour la même raison que vous ne pouvez pas convertir DateTime en string)

Vous devez transtyper en object, (que n'importe quel T peut transtyper), puis à partir de string (puisque object peut être converti en string).
Par exemple:

T newT1 = (T)(object)"some text";
string newT2 = (string)(object)t;
258
SLaks

Les deux lignes ont le même problème

T newT1 = "some text";
T newT2 = (string)t;

Le compilateur ne sait pas que T est une chaîne et n'a donc aucun moyen de savoir comment l'affecter. Mais puisque vous avez coché, vous pouvez simplement le forcer avec

T newT1 = "some text" as T;
T newT2 = t; 

vous n'avez pas besoin de lancer le t puisqu'il est déjà une chaîne, vous devez également ajouter la contrainte

where T : class
9
Doggett

Si vous recherchez des types explicites, pourquoi déclarez-vous ces variables comme étant T?

T HowToCast<T>(T t)
{
    if (typeof(T) == typeof(string))
    {
        var newT1 = "some text";
        var newT2 = t;  //this builds but I'm not sure what it does under the hood.
        var newT3 = t.ToString();  //for sure the string you want.
    }

    return t;
}
1
Austin Salonen

Vous obtiendrez également cette erreur si vous avez une déclaration générique à la fois pour votre classe et votre méthode. Par exemple, le code ci-dessous donne cette erreur de compilation.

public class Foo <T> {

    T var;

    public <T> void doSomething(Class <T> cls) throws InstantiationException, IllegalAccessException {
        this.var = cls.newInstance();
    }

}

Ce code compile (note T retiré de la déclaration de la méthode):

public class Foo <T> {

    T var;

    public void doSomething(Class <T> cls) throws InstantiationException, IllegalAccessException {
        this.var = cls.newInstance();
    }

}
0
John