2010-10-01 2 views

Répondre

6

La variance générique ne fonctionne qu'avec les types de référence, oui. (C'est pour que le CLR sache que tout est encore juste une référence, donc le code JITTED est toujours le même ... les bits impliqués dans une référence sont les mêmes quel que soit le type dont vous parlez, alors que traiter int comme object nécessite un conversion de boxe.Base basiquement vous pouvez garder representational identity avec les types de référence).

Du C# 4 spec, section 13.1.3.2:

Un type T<A1, …, An> est la variance convertible à un type T<B1, …, Bn> si T est soit une interface ou d'un type délégué déclarée avec les paramètres de type de variante T<X1, …, Xn>, et pour chaque paramètre de type de variante Xi une des situations suivantes est vérifiée:

  • Xi est covariant et une référence implicite ou conversion d'identité existe de Ai Bi
  • Xi est contra variante et une référence implicite ou la conversion d'identité existe de Bi Ai
  • Xi est invariant et une conversion d'identité existe de Ai Bi

Il est la « conversion de référence implicite » plutôt que la « conversion implicite » bit qui est un problème pour les types de valeur.

Pour beaucoup plus de détails sur la variance générique, voir Eric Lippert's blog series on the topic.

+0

thx, j'ai eu le sentiment que la réponse est "à cause de spec", mais il est très décevant que les types de valeur ne sont pas invités à la fête. – Andrey

+3

@Andrey: "à cause de la spécification" implique que la décision était arbitraire, mais ce n'était pas le cas. Jon explique pourquoi pas: parce que int et object ne sont pas des types * compatibles *. Une fonction qui retourne un int ne peut pas être utilisée comme une fonction qui renvoie un objet car une fonction qui retourne un entier écrit un entier de 32 bits dans le stockage de retour, et une fonction qui retourne un objet écrit un pointeur, par exemple 64 bits, un objet affecté par le tas dans le stockage de retour. Les exigences de taille de stockage * ne sont même pas les mêmes, donc les types ne sont tout simplement pas compatibles. –

+1

@Andrey: Maintenant, nous pourrions, en théorie, rendre la variance légale parmi les types de valeur qui ont une représentation préservant les conversions. Func et Func par exemple auraient pu être rendus compatibles. Mais cela semblait juste une bonne quantité de travail pour aucun avantage convaincant. Très peu de types de valeurs sont compatibles avec les bits et ont la même sémantique; vous ne voudriez pas qu'un Func soit utilisé comme Func même s'il s'agit des deux types 64 bits. –

Questions connexes