Как перегрузить оператор квадратной скобки в C #? - PullRequest
230 голосов
/ 13 ноября 2008

DataGridView, например, позволяет вам сделать это:

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

но я не могу найти документацию по оператору индекса / квадратной скобки. Как они это называют? Где это реализовано? Это может бросить? Как я могу делать то же самое в своих классах?

ETA: Спасибо за все быстрые ответы. Вкратце: соответствующая документация находится в собственности «Item»; способ перегрузки заключается в объявлении свойства типа public object this[int x, int y]{ get{...}; set{...} }; индексатор для DataGridView не выбрасывает, по крайней мере, согласно документации. Не упоминается, что произойдет, если вы введете неверные координаты.

ETA Опять же: ОК, хотя документация не упоминает об этом (непослушная Microsoft!), Оказывается, что индексатор для DataGridView фактически вызовет исключение ArgumentOutOfRangeException, если вы предоставите ему недопустимые координаты. Справедливое предупреждение.

Ответы [ 8 ]

348 голосов
/ 13 ноября 2008

вы можете найти, как это сделать здесь . Короче это:

public object this[int i]
{
    get { return InnerList[i]; }
    set { InnerList[i] = value; }
}
40 голосов
/ 13 ноября 2008

Это было бы свойство элемента: http://msdn.microsoft.com/en-us/library/0ebtbkkc.aspx

Может быть, что-то вроде этого будет работать:

public T Item[int index, int y]
{ 
    //Then do whatever you need to return/set here.
    get; set; 
}
24 голосов
/ 13 ноября 2008
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!

Источник информации

Для кронштейна:

public Object this[int index]
{

}

НО

Оператор индексации массива не может быть перегружен ; однако типы могут определять индексаторы, свойства, которые принимают один или несколько параметров. Параметры индексатора заключены в квадратные скобки, как и индексы массива, но параметры индексатора можно объявить любого типа (в отличие от индексов массива, которые должны быть целыми).

С MSDN

6 голосов
/ 13 ноября 2008
public class CustomCollection : List<Object>
{
    public Object this[int index]
    {
        // ...
    }
}
4 голосов
/ 05 декабря 2015

Если вы используете C # 6 или новее, вы можете использовать синтаксис тела выражения для индексатора только для получения:

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

4 голосов
/ 21 ноября 2008

Для CLI C ++ (скомпилировано с / clr) см. эту ссылку MSDN .

Короче говоря, свойству может быть присвоено имя "default":

ref class Class
{
 public:
  property System::String^ default[int i]
  {
    System::String^ get(int i) { return "hello world"; }
  }
};
2 голосов
/ 13 ноября 2008

Вот пример, возвращающий значение из внутреннего объекта List. Должен дать вам идею.

  public object this[int index]
  {
     get { return ( List[index] ); }
     set { List[index] = value; }
  }
1 голос
/ 13 ноября 2008

Если вы имеете в виду индексатор массива, вы перегружаете его, просто записывая свойство индексатора. И вы можете перегружать (записывать столько, сколько хотите) свойств индексатора, если каждое из них имеет свою сигнатуру параметра

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;
        }
    }
}
...