DataGridView, например, позволяет сделать это:
DataGridView dgv = ...;
DataGridViewCell cell = dgv[1,5];
но хоть убей, я не могу найти документацию по оператору индекса / квадратной скобки. Как они это называют? Где это реализовано? Может его выкинуть? Как я могу делать то же самое в своих классах?
ETA: Спасибо за все быстрые ответы. Вкратце: соответствующая документация находится в свойстве «Предмет»; способ перегрузки - объявить свойство наподобие public object this[int x, int y]{ get{...}; set{...} }; индексатор для DataGridView не кидает, по крайней мере согласно документации. Не упоминается, что произойдет, если вы укажете неверные координаты.
ETA Again: Хорошо, хотя в документации об этом не упоминается (непослушный Microsoft!), Оказывается, что индексатор для DataGridView на самом деле выдаст исключение ArgumentOutOfRangeException, если вы предоставите ему недопустимые координаты. Справедливое предупреждение.





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
Может, но не для того условия, которое я написал. Это из MSDN. Проверьте источник, если вы мне не верите
Извините, если я неправильно прочитал ваш пост, но какое условие вы имеете в виду?
+1 за удобный список. К вашему сведению ссылка умерла. (4 года спустя, я знаю)
Я хотел бы добавить, что теперь вы можете переопределить как неявное, так и явное приведение типов в C#.
public class CustomCollection : List<Object>
{
public Object this[int index]
{
// ...
}
}
На самом деле это действительно опасно - теперь у вас есть две конкурирующие реализации: любой, у кого переменная введена как List <T> или IList <T> или IList и т. д., Не будет выполнять ваш собственный код.
Согласен - по крайней мере, нет необходимости выводить CustomCollection из List, но я не осознавал, что это действительно опасно
Однако он по-прежнему будет выполнять собственный код, не так ли? Неважно, какой тип переменной вы объявляете - имеет значение тип объекта.
Если вы передадите объект функции, принимающей List <Object>, тогда пользовательский код не будет вызван
Дружественное напоминание о полиморфизме C#: это происходит потому, что базовый класс не объявляет свою реализацию как виртуальную. Если бы он был объявлен как виртуальный, в каждом случае вызывался бы пользовательский код.
Кроме того, этот код выдаст предупреждение компилятору, поскольку оба индексатора не являются виртуальными. Компилятор предложит вам указать в своем пользовательском индексаторе ключевое слово new.
вы можете узнать, как это сделать здесь. Вкратце это:
public object this[int i]
{
get { return InnerList[i]; }
set { InnerList[i] = value; }
}
Если вам нужен только геттер, можно также использовать синтаксис в ответ ниже (начиная с C# 6).
небольшой комментарий: в зависимости от того, что вы делаете, вам может показаться более подходящим: get {return base [i]; } установить {base [i] = значение; }
Это не перегрузка оператора. Это индексатор
Индексатор также может быть унарным оператором.
В 2019 году следует выбрать новый ответ, Вот этот. Жаль, что у SO нет функции для работы с устаревшими ответами, поскольку новый еще не близок к тому, чтобы получить 350+ голосов, хотя он их заслуживает.
@mins Я добавил ссылку на другой ответ.
Это будет свойство элемента: 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;
}
Большое спасибо! Если бы я мог задать два ответа, я бы добавил и ваш - никто другой не знал, что искать Item в документации ...
С точки зрения того, как это реализуется, это «Item», но в терминах C# это «this».
Верно, но я спросил: «Да здравствует я, я не могу найти документацию по оператору индекса / квадратной скобки» - я имел в виду, когда вы просматриваете класс библиотеки в MSDN, где они говорят вам об операторе? Вот почему я сделал последнее "ETA" о том, что он бросает - это неправильный.
Вот пример, возвращающий значение из внутреннего объекта List. Должен дать вам идею.
public object this[int index]
{
get { return ( List[index] ); }
set { List[index] = value; }
}
Если вы имеете в виду индексатор массива, вы перегружаете его, просто записывая свойство индексатора. И вы можете перегружать (писать столько, сколько хотите) свойства индексатора, если каждый из них имеет другую сигнатуру параметра
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;
}
}
}
Во-первых, вы имеете в виду this [], а не this () - однако предоставление специального (но другого) this [int] для чего-то, что является списком (IList / IList <T> / List <T>), довольно опасно - и может привести к незаметным ошибкам между версиями "int index" и "int employeeId". Оба по-прежнему можно отозвать.
и на самом деле я не думаю, что код, который я ввел выше, будет компилироваться без добавления оператора new или override именно из-за существования List <T> реализации this [int]. Вы правы насчет потенциала, когда делаете это, просто имел в виду это как пример перегрузки индексатора.
Для CLI C++ (скомпилированного с / clr) см. эта ссылка MSDN.
Вкратце, свойству можно присвоить имя «по умолчанию»:
ref class Class
{
public:
property System::String^ default[int i]
{
System::String^ get(int i) { return "hello world"; }
}
};
Если вы используете C# 6 или новее, вы можете использовать синтаксис с выражением для индексатора только для получения:
public object this[int i] => this.InnerList[i];
да, он может быть перегружен, если подпись параметра отличается, точно так же, как и ограничения перегрузки любого другого метода