How do I overload the square-bracket operator in C#?

139,201

Solution 1

you can find how to do it here. In short it is:

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

If you only need a getter the syntax in answer below can be used as well (starting from C# 6).

Solution 2

That would be the item property: http://msdn.microsoft.com/en-us/library/0ebtbkkc.aspx

Maybe something like this would work:

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

Solution 3

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 of the information

For bracket:

public Object this[int index]
{
    
}

##BUT

The array indexing operator cannot be overloaded; however, types can define indexers, properties that take one or more parameters. Indexer parameters are enclosed in square brackets, just like array indices, but indexer parameters can be declared to be of any type (unlike array indices, which must be integral).

From MSDN

Solution 4

If you're using C# 6 or later, you can use expression-bodied syntax for get-only indexer:

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

Solution 5

public class CustomCollection : List<Object>
{
    public Object this[int index]
    {
        // ...
    }
}
Share:
139,201

Related videos on Youtube

Coderer
Author by

Coderer

Updated on February 23, 2022

Comments

  • Coderer
    Coderer about 2 years

    DataGridView, for example, lets you do this:

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

    but for the life of me I can't find the documentation on the index/square-bracket operator. What do they call it? Where is it implemented? Can it throw? How can I do the same thing in my own classes?

    ETA: Thanks for all the quick answers. Briefly: the relevant documentation is under the "Item" property; the way to overload is by declaring a property like public object this[int x, int y]{ get{...}; set{...} }; the indexer for DataGridView does not throw, at least according to the documentation. It doesn't mention what happens if you supply invalid coordinates.

    ETA Again: OK, even though the documentation makes no mention of it (naughty Microsoft!), it turns out that the indexer for DataGridView will in fact throw an ArgumentOutOfRangeException if you supply it with invalid coordinates. Fair warning.

  • Coderer
    Coderer over 15 years
    Thanks a lot! If I could set two answers, I'd add yours as well -- nobody else knew to look for Item in the documentation...
  • Charles Bretana
    Charles Bretana over 15 years
    yes it can be overloaded, as long as the parameter signature is different, exactly like any other method's overloading restrictions
  • Patrick Desjardins
    Patrick Desjardins over 15 years
    It can, but not for the condition I wrote. It's from MSDN. Check the source if you do not believe me
  • Marc Gravell
    Marc Gravell over 15 years
    Actually, this is really dangerous - you now have two competing implementations: anyone with a variable typed as List<T> or IList<T> or IList etc won't execute your custom code.
  • Marc Gravell
    Marc Gravell over 15 years
    First, you mean this[], not this() - however, providing a custom (but different) this[int] on something that is a list (IList/IList<T>/List<T>) is quite dangerous - and could lead to subtle bugs between the "int index" and "int employeeId" versions. Both are still callable.
  • Charles Bretana
    Charles Bretana over 15 years
    and in fact, I don;t think the code I entered above would compile without adding a new or override statement precisely because of the existence of the List<T> implementation of this[int]. You're right about the potential when doing this, simply meant it as example of overloading indexer.
  • Coderer
    Coderer over 15 years
    Right, but I asked "for the life of me I can't find the documentation on the index/square-bracket operator" -- I meant when you look up a library class in MSDN, where do they tell you about the operator? That's why I made that last "ETA" about what it throws -- the docs are wrong.
  • izb
    izb over 13 years
    It will still execute the custom code though, won't it? It doesn't matter what variable type you declare - it's the type of the object that matters.
  • David Sykes
    David Sykes about 12 years
    If you pass the object to a function accepting List<Object> then the custom code is not called
  • MikeBaz - MSFT
    MikeBaz - MSFT over 11 years
    a minor comment: depending on what you're doing, you might find it more appropriate to do: get { return base[i]; } set { base[i] = value; }
  • Mixxiphoid
    Mixxiphoid about 11 years
    +1 for the handy list. FYI the link died. (4 years later, I know)
  • almulo
    almulo almost 9 years
    Friendly reminder of C# polymorphism: That happens because the base class doesn't declare its implementation as virtual. If it were declared as virtual, the custom code would be called in every case.
  • Destructor
    Destructor almost 8 years
    This isn't operator overloading. It is indexer
  • amoss
    amoss almost 8 years
    Also, this code will give you a compiler warning since both indexers are non-virtual. The compiler will suggest that you qualify your custom indexer with the new keyword.
  • alan2here
    alan2here over 7 years
    Indexer, may as well be a unary operator.
  • Felype
    Felype over 6 years
    I'd like to add that you can override both implicit and explicit type-casting in C# now.
  • mins
    mins almost 5 years
    In 2019, a new answer should be selected, this one. Too bad SO doesn't have a feature to deal with deprecated answers, as the new one is not close to get 350+ upvotes, though it deserves them.
  • Ruben
    Ruben almost 5 years
    @mins I included a link to the other answer.