2010-10-24 36 views
4

Pourquoi est-ce que je ne peux qu'atteindre un générique et ne pas le baisser?
Comment n'est-il pas clair pour le compilateur que si ma contrainte indique where T : BaseClass et U est dérivé de BaseClass que (U)objectOfTypeT est valide?Dédouanement d'un type générique en C# 3.5

+2

Si elle aide, notez que vous pouvez ajouter un casting à l'objet au milieu si vous voulez passer outre le compilateur. –

+1

@ Marc Gravell: Cela aide beaucoup. Merci. –

Répondre

5

Parce que cela pourrait ne pas être valide. Considérez ceci:

class Base { } 
class A : Base { } 
class B : Base { } 

A temp1 = new A(); 
B temp2 = (B)temp1; // not valid 

Tout simplement parce qu'ils partagent la même classe de base ne signifie pas que vous pouvez typer un à l'autre.

Notez que vous pouvez contourner ce problème en utilisant l'opérateur as:

var result = objectOfTypeT as U; // this does not give any compilation error 
           // but will result in a null reference if 
           // objectOfTypeT cannot be converted to U 
+0

Alors pourquoi ne pas lancer une exception comme toujours? "Cast non valide" –

+0

@the_drow: Je ne peux que spéculer, mais on dirait que cela contrecarrerait le but des génériques; un élément clé des génériques est de parvenir à la sécurité du type. Autoriser cette distribution potentiellement défaillante irait à l'encontre de cet objectif. –

+0

Après avoir cherché google un peu. Qu'en est-il de la covariance et de la contravariance? Est-ce que c'est ce que je cherche? –

2

À moins que je lis la mauvaise question, vous pourriez avoir:

class A:BaseClass{} 
class B:BaseClass{} 

Avec T = A et U = B, les deux contraintes sont heureux, mais la distribution de T à U est clairement invalide.

Si U est juste une autre classe, alors la même chose s'applique toujours; le T n'est pas connu pour être dans la même chaîne que U sauf si vous l'énoncez dans les contraintes (les contraintes génériques peuvent impliquer d'autres arguments de type générique, si cela aide).

+0

Eh bien non, je ne lance pas de T à U mais de T à A où T est A et la contrainte est où T: BaseClass. –

+0

@the_drow (U) objectOfTypeT est certainement une distribution de T à U –