C'est probablement une question 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 fond C ++, je m'attendais à ce que cela fonctionne. Cependant, il ne parvient pas à compiler 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.
Soit je fais quelque chose de mal conceptuel, soit j'ai simplement la mauvaise syntaxe. S'il vous plaît, aidez-moi à régler celui-ci.
Je vous remercie!
typeof(T) == typeof(string)
est résolue au moment de l'exécution, pas au moment de la compilation. Ainsi, la ligne suivante du bloc n'est pas valide.Réponses:
Même si c'est à l'intérieur d'un
if
bloc, le compilateur ne sait pas queT
c'eststring
.Par conséquent, il ne vous permet pas de lancer. (Pour la même raison que vous ne pouvez pas lancer
DateTime
àstring
)Vous devez lancer vers
object
, (vers lequel n'importe quiT
peut lancer), et de là versstring
(puisqueobject
peut être lancé versstring
).Par exemple:
la source
T
:var isBlank = (userDefinedValue is string) && String.IsNullOrWhiteSpace(userDefinedValue as string);
Les deux lignes ont le même problème
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 vérifié, vous pouvez simplement le forcer avec
vous n'avez pas besoin de transtyper le t car c'est déjà une chaîne, vous devez également ajouter la contrainte
la source
Je connais un code similaire que l'OP a publié dans cette question à partir d'analyseurs génériques. Du point de vue des performances, vous devez utiliser
Unsafe.As<TFrom, TResult>(ref TFrom source)
, qui se trouve dans le package NuGet System.Runtime.CompilerServices.Unsafe . Cela évite de boxer pour les types valeur dans ces scénarios. Je pense aussi que celaUnsafe.As
entraîne moins de code machine produit par le JIT que de lancer deux fois (en utilisant(TResult) (object) actualString
), mais je ne l'ai pas vérifié.Unsafe.As
sera remplacé par le JIT avec des instructions de code machine efficaces, comme vous pouvez le voir dans le repo officiel CoreFX:la source
Si vous recherchez des types explicites, pourquoi déclarez-vous ces variables comme
T
des s?la source
T
.object
valeurs, avec des types dérivés qui stockent lesstring
valeurs. Supposons que ces champs aient également une valeur "DefaultIfNotProvided", vous devez donc vérifier si la valeur fournie par l'utilisateur (qui peut être un objet ou une chaîne ou même une primitive numérique) est équivalente àdefault(T)
. La chaîne peut être traitée comme un cas spécial où une chaîne vide / d'espacement est traitée de la même manière que la valeur par défaut (T), vous pouvez donc vérifier siT userValue; var isBlank = (userValue is string) && String.IsNullOrWhitespace(userValue as string);
.Vous obtiendrez également cette erreur si vous avez une déclaration générique pour votre classe et votre méthode. Par exemple, le code ci-dessous donne cette erreur de compilation.
Ce code compile (note T retiré de la déclaration de méthode):
la source
Changez cette ligne:
Pour cette ligne:
la source