web-dev-qa-db-fra.com

Pourquoi le nouvel index d'opérateur de chapeau de la fonction de découpage de tableau C # 8 ne démarre-t-il pas à 0?

C # 8.0 présente un moyen pratique de découper les tableaux - voir blogpost officiel C # 8. .

La syntaxe pour accéder au dernier élément d'un tableau est

int value[] = { 10, 11, 12, 13 };

int a = value[^1]; // 13
int b = value[^2]; // 12

Je me demande pourquoi l'indexation pour accéder aux éléments en arrière commence à 1 au lieu de 0? Y a-t-il une raison technique à cela?

153
Michael Pittino

Réponse officielle

Pour une meilleure visibilité, voici un commentaire de Mads Torgersen expliquant cette décision de conception dans le article de blog C # 8 :

Nous avons décidé de suivre Python en ce qui concerne l'arithmétique de début et de fin. 0 Désigne le premier élément (comme toujours), et ^0 L'élément "length’th", c'est-à-dire celui qui se trouve juste à la fin. De cette façon, vous obtenez une relation simple, où la position d'un élément depuis le début plus sa position depuis la fin est égale à la longueur. le x dans ^x Est ce que vous auriez soustrait de la longueur si vous aviez fait le calcul vous-même.

Pourquoi ne pas utiliser le signe moins (-) au lieu du nouveau chapeau (^) opérateur? Cela concerne principalement les plages. Toujours en accord avec Python et la plupart de l'industrie, nous voulons que nos plages soient inclusives au début, exclusives à la fin. Quel est l'indice que vous passez pour dire qu'une plage devrait aller tout le chemin vers la fin? En C # la réponse est simple: x..^0 va de x à la fin. En Python, il n'y a pas d'index explicite que vous pouvez donner: -0 ne fonctionne pas, car il est égal à 0, le premier élément! Donc, en Python, vous devez laisser complètement l'index de fin pour exprimer une plage qui va à la fin: x... Si la fin de la plage est calculée, alors vous devez vous rappeler d'avoir une logique spéciale au cas où elle sortirait à 0. Un péché x..-y, où y a été calculé et est sorti vers 0. C'est une nuisance courante et une source de bugs.

Enfin, notez que les indices et les plages sont des types de première classe en .NET/C #. Leur comportement n'est pas lié à ce à quoi ils sont appliqués, ni même à être utilisé dans un indexeur. Vous pouvez définir totalement votre propre indexeur qui prend Index et un autre qui prend Range - et nous allons ajouter de tels indexeurs par exemple Span. Mais vous pouvez également avoir des méthodes qui prennent des plages, par exemple.

Ma réponse

Je pense que cela correspond à la syntaxe classique à laquelle nous sommes habitués:

value[^1] == value[value.Length - 1]

S'il utilisait 0, ce serait déroutant lorsque les deux syntaxes étaient utilisées côte à côte. De cette façon, il a une charge cognitive inférieure.

D'autres langages comme Python utilisent également la même convention.

168
Martin Zikmund