2010-08-18 20 views
7

J'ai de la difficulté à comprendre pourquoi les tableaux en C# sont covariants et quels avantages cette covariance peut apporter. Prenons l'exemple de code trivial suivant:Pourquoi les tableaux C# sont-ils covariants et quels sont les avantages?

object[] myArray = new string[1]; 
myArray[0] = 1; 

Ce code compilera correct, mais sans cérémonie et peut-être exploser sans surprise lors de l'exécution. Si j'essaye de faire la même chose en utilisant des génériques, le compilateur me gronderait et je réaliserais ma bêtise à un stade précoce, donc ma question est la suivante: pourquoi le compilateur C# permet-il cette covariance avec des tableaux et en plus , Quels sont les bénéfices potentiels?

Répondre

12

Eric Lippert dit:

U Malheureusement, ce type particulier de covariance est brisé. Il a été ajouté au CLR parce que Java l'exige et les concepteurs de CLR voulaient être capables de supporter des langages de type Java. Nous l'avons ensuite ajouté à C# parce que c'était dans le CLR. Cette décision était très controversée à l'époque et je ne suis pas très heureux à ce sujet, mais il n'y a rien que nous puissions faire à ce sujet maintenant.

4
+3

mquander gagne pour avoir cité le blog au lieu de simplement le lier. –

+1

@Jon B - et pour citer le bit _relevant_. – Oded

+0

Merci pour les liens vers des informations supplémentaires. Très utile. – nukefusion

1

Il existe de nombreuses situations dans lesquelles le code va se déplacer ou copier des éléments entre les emplacements d'un tableau. A condition que Arr soit un tableau unidimensionnel avec au moins deux éléments, le code suivant fonctionnera quel que soit le type de Arr ou les éléments qu'il contient.

Object temp = Arr[1]; 
Arr[1] = Arr[0]; 
Arr[0] = temp; 

Ce code sera inefficace si Arr est un type de valeur, mais comme temp est lu du tableau, le type du tableau est garantie pour être capable de tenir une telle valeur. Le code devra encadrer et unbox des éléments de type valeur, et sera donc inefficace avec de tels types, mais cela fonctionnera malgré tout. Notez que lors de la création de tableaux covariants est une façon de permettre à des choses telles que les méthodes de tri de fonctionner sur des types de tableaux arbitraires, ce n'est pas le seul. Une autre approche serait d'avoir System.Array inclure quelques méthodes et propriétés dont les paramètres n'ont aucun rapport avec le type d'élément sous-jacent. Par exemple, il pourrait inclure quelques méthodes simples comme Swap, CopyItem, et Roll, et éventuellement des méthodes pour effectuer des permutations plus complexes étant donné une liste d'indices. Notez que contrairement au code indiqué ci-dessus, un type comme Int[] peut remplacer sa méthode Swap de manière à éviter la boxe et le déballage.