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

C#CollectionsOperatorsOperator Overloading

C# Problem Overview


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.

C# Solutions


Solution 1 - C#

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 - C#

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 - C#

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 - C#

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 - C#

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

Solution 6 - C#

For CLI C++ (compiled with /clr) see this MSDN link.

In short, a property can be given the name "default":

ref class Class
{
 public:
  property System::String^ default[int i]
  {
    System::String^ get(int i) { return "hello world"; }
  }
};

Solution 7 - C#

Here is an example returning a value from an internal List object. Should give you the idea.

  public object this[int index]
  {
     get { return ( List[index] ); }
     set { List[index] = value; }
  }

Solution 8 - C#

If you mean the array indexer,, You overload that just by writing an indexer property.. And you can overload, (write as many as you want) indexer properties as long as each one has a different parameter signature

public class EmployeeCollection: List<Employee>
{
    public Employee this[int employeeId]
    {   
        get 
        { 
            foreach(var emp in this)
            {
                if (emp.EmployeeId == employeeId)
                    return emp;
            }

            return null;
        }
    }
    
    public Employee this[string employeeName]
    {   
        get 
        { 
            foreach(var emp in this)
            {
                if (emp.Name == employeeName)
                    return emp;
            }

            return null;
        }
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCodererView Question on Stackoverflow
Solution 1 - C#RubenView Answer on Stackoverflow
Solution 2 - C#Ricardo VillamilView Answer on Stackoverflow
Solution 3 - C#Patrick DesjardinsView Answer on Stackoverflow
Solution 4 - C#amossView Answer on Stackoverflow
Solution 5 - C#Jason MiesionczekView Answer on Stackoverflow
Solution 6 - C#superjordoView Answer on Stackoverflow
Solution 7 - C#Rob ProuseView Answer on Stackoverflow
Solution 8 - C#Charles BretanaView Answer on Stackoverflow