187 votes

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

C# 8.0 introduit un moyen pratique de découper les tableaux - voir billet de blog officiel sur C# 8.0 .

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

var value = new[] { 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 à l'envers commence à 1 au lieu de 0 ? Y a-t-il une raison technique à cela ?

17 votes

Notez que les plages C++ sont également [beginInclusive, endExclusive) . C'est une convention courante.

4 votes

@Sinatr : En se basant sur cet article de blog, la syntaxe pour tout renvoyer serait la suivante value[0..^0] puisque l'indice de terminaison est exclusif (c'est aussi le cas dans la plupart des autres langues). C'est également pratique, value[^i..^0] vous donnera le dernier i articles.

2 votes

@bommelding : C++ rbegin() n'est pas tout à fait d'accord avec cette idée : le premier élément de cette gamme n'est pas non plus celui qui va le plus loin ;-)

199voto

MZetko Points 1612

Réponse officielle

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

Nous avons décidé de suivre Python en ce qui concerne l'arithmétique du début et de la fin.  0  désigne le premier élément (comme toujours), et  ^0  le "length'th" élément, 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 par rapport au début plus sa position par rapport à la fin est égale à la longueur. the  x  sur  ^x  est ce que vous auriez soustrait de la longueur si vous aviez fait le calcul vous-même.

Pourquoi ne pas utiliser le moins ( - ) au lieu du nouveau chapeau ( ^ ) ? Cela concerne principalement les plages. Encore une fois, conformément à Python et à la plupart des entreprises, nous voulons que nos plages soient inclusives au début et exclusives à la fin. Quel est l'indice que vous passez pour dire qu'une plage doit aller jusqu'à la fin ? En C#, la réponse est simple : x..^0 va de  x  jusqu'à la fin. En Python, il n'y a pas d'indice explicite que vous pouvez donner : -0 ne fonctionne pas, car il est égal à 0 le premier élément ! Ainsi, en Python, vous devez laisser l'indice de fin complètement absent pour exprimer une plage qui va jusqu'à la fin : x.. . Si la fin de l'intervalle est calculée, vous devez vous rappeler d'avoir une logique spéciale au cas où il s'agirait de 0 . Comme dans x..-y , donde y a été calculée et s'est avérée être 0 . C'est une nuisance courante et une source d'insectes.

Enfin, notez que les indices et les plages sont des types de première classe dans .NET/C#. Leur comportement n'est pas lié à ce à quoi ils sont appliqués, ni même à leur utilisation dans un indexeur. Vous pouvez tout à fait définir 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 aussi avoir des méthodes qui prennent des plages, par exemple.

Ma réponse

Je pense que c'est pour correspondre à la syntaxe classique à laquelle nous sommes habitués :

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

S'il utilisait 0, il y aurait confusion lorsque les deux syntaxes sont utilisées côte à côte. De cette façon, il a inférieur la charge cognitive.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X