273 votes

Comment surcharger l'opérateur de crochets en C# ?

DataGridView, par exemple, vous permet de le faire :

DataGridView dgv = ...;
DataGridViewCell cell = dgv[1,5];

mais je n'arrive pas à trouver la documentation sur l'opérateur index/carré. Comment l'appelle-t-on ? Où est-il implémenté ? Peut-il être lancé ? Comment puis-je faire la même chose dans mes propres classes ?

ETA : Merci pour toutes les réponses rapides. En bref : la documentation pertinente se trouve sous la propriété "Item" ; la façon de surcharger est de déclarer une propriété comme public object this[int x, int y]{ get{...}; set{...} } l'indexeur pour DataGridView ne lance pas, du moins selon la documentation. Elle ne mentionne pas ce qui se passe si vous fournissez des coordonnées invalides.

ETA encore : OK, même si la documentation n'en fait pas mention (vilain Microsoft !), il s'avère que l'indexeur de DataGridView lèvera en fait une exception ArgumentOutOfRangeException si vous lui fournissez des coordonnées invalides. C'est un avertissement.

413voto

Ruben Points 3288

Vous pouvez trouver comment le faire aquí . En bref, c'est :

public object this[int i]
{
    get { return InnerList[i]; }
    set { InnerList[i] = value; }
}

Si vous avez seulement besoin d'un getter, la syntaxe dans réponse ci-dessous peut également être utilisé (à partir de C# 6).

9 votes

Un commentaire mineur : selon ce que vous faites, vous pourriez trouver plus approprié de faire : get { return base[i] ; } set { base[i] = value ; }

9 votes

Ce n'est pas une surcharge d'opérateurs. C'est un indexeur

6 votes

Indexer, peut tout aussi bien être un opérateur unaire.

44voto

Ricardo Villamil Points 3080

Ce serait la propriété de l'élément : http://msdn.microsoft.com/en-us/library/0ebtbkkc.aspx

Peut-être que quelque chose comme ça pourrait fonctionner :

public T Item[int index, int y]
{ 
    //Then do whatever you need to return/set here.
    get; set; 
}

0 votes

Merci beaucoup ! Si je pouvais mettre deux réponses, j'ajouterais aussi la vôtre - personne d'autre ne savait qu'il fallait chercher Item dans la documentation...

5 votes

En termes d'implémentation, c'est "Item", mais en C#, c'est "this".

1 votes

C'est vrai, mais j'ai demandé "je n'arrive pas à trouver la documentation sur l'opérateur index/carré" -- je voulais dire que lorsque vous cherchez une classe de bibliothèque dans MSDN, où est-ce qu'on vous parle de l'opérateur ? C'est pourquoi j'ai fait cette dernière "ETA" sur ce qu'il jette -- les docs sont mauvais .

28voto

Patrick Desjardins Points 51478
Operators                           Overloadability

+, -, *, /, %, &, |, <<, >>         All C# binary operators can be overloaded.

+, -, !,  ~, ++, --, true, false    All C# unary operators can be overloaded.

==, !=, <, >, <= , >=               All relational operators can be overloaded, 
                                    but only as pairs.

&&, ||                  They can't be overloaded

() (Conversion operator)        They can't be overloaded

+=, -=, *=, /=, %=                  These compound assignment operators can be 
                                    overloaded. But in C#, these operators are
                                    automatically overloaded when the respective
                                    binary operator is overloaded.

=, . , ?:, ->, new, is, as, sizeof  These operators can't be overloaded

    [ ]                             Can be overloaded but not always!

Source de l'information

Pour le support :

public Object this[int index]
{

}

PERO

L'opérateur d'indexation de tableau ne peut pas être surchargé Cependant, les types peuvent définir des indexeurs, des propriétés qui prennent un ou plusieurs paramètres. Les paramètres des indexeurs sont placés entre crochets, tout comme les indices de tableaux, mais les paramètres des indexeurs peuvent être déclarés de n'importe quel type (contrairement aux indices de tableaux, qui doivent être intégraux).

De MSDN

0 votes

Oui, elle peut être surchargée, à condition que la signature du paramètre soit différente, exactement comme les restrictions de surcharge de n'importe quelle autre méthode.

0 votes

C'est possible, mais pas pour la condition que j'ai écrite. Ça vient de MSDN. Vérifiez la source si vous ne me croyez pas

2 votes

Désolé si j'ai mal lu votre message, mais à quelle condition faites-vous référence ?

17voto

amoss Points 445

Si vous utilisez C# 6 ou une version ultérieure, vous pouvez utiliser la syntaxe à base d'expressions pour l'indexeur get-only :

public object this[int i] => this.InnerList[i];

5voto

Jason Miesionczek Points 7033
public class CustomCollection : List<Object>
{
    public Object this[int index]
    {
        // ...
    }
}

6 votes

En fait, c'est vraiment dangereux - vous avez maintenant deux implémentations concurrentes : toute personne ayant une variable typée comme List<T> ou IList<T> ou IList etc. n'exécutera pas votre code personnalisé.

1 votes

Je suis d'accord -- il n'est pas nécessaire de faire dériver votre CustomCollection de List, mais je n'avais pas réalisé que c'était dangereux.

0 votes

Il exécutera quand même le code personnalisé, n'est-ce pas ? Le type de variable que vous déclarez n'a pas d'importance - c'est le type de l'objet qui compte.

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