Я знаю, я знаю... Ответ Эрика Липперта на этот вопрос обычно похож на "потому что он не стоил затрат на проектирование, внедрение, тестирование и документирование".
Но все же я хотел бы получить лучшее объяснение... Я читал это сообщение в блоге о новых функциях С# 4, а также в раздел о COM Interop, следующее внимание привлекло мое внимание:
Кстати, этот код использует еще одну новую функцию: индексированные свойства (более подробно рассмотрим эти квадратные скобки после Range.) Но эта функция доступна только для COM-взаимодействия; вы не можете создавать свои собственные индексированные свойства в С# 4.0.
ОК, но почему? Я уже знал и сожалел о невозможности создания индексированных свойств в С#, но это предложение заставило меня задуматься об этом. Я вижу несколько веских причин для его реализации:
- CLR поддерживает его (например,
PropertyInfo.GetValue
имеет параметрindex
), поэтому нам жаль, что мы не можем использовать его в С# - поддерживается для COM-взаимодействия, как показано в статье (с использованием динамической отправки)
- он реализован в VB.NET
- уже можно создавать индексы, т.е. применять индекс к самому объекту, поэтому, вероятно, не будет большой проблемой расширить идею до свойств, сохранив тот же синтаксис и просто заменив
this
на имя свойства
Это позволило бы написать такие вещи:
public class Foo
{
private string[] _values = new string[3];
public string Values[int index]
{
get { return _values[index]; }
set { _values[index] = value; }
}
}
В настоящее время единственным обходным решением, которое я знаю, является создание внутреннего класса (например, ValuesCollection
), который реализует индекс, и изменяет свойство Values
, чтобы он возвращал экземпляр этого внутреннего класса.
Это очень легко сделать, но раздражает... Поэтому, возможно, компилятор мог сделать это для нас! Параметр должен был бы создать внутренний класс, который реализует индексатор, и выставить его через общий общий интерфейс:
// interface defined in the namespace System
public interface IIndexer<TIndex, TValue>
{
TValue this[TIndex index] { get; set; }
}
public class Foo
{
private string[] _values = new string[3];
private class <>c__DisplayClass1 : IIndexer<int, string>
{
private Foo _foo;
public <>c__DisplayClass1(Foo foo)
{
_foo = foo;
}
public string this[int index]
{
get { return _foo._values[index]; }
set { _foo._values[index] = value; }
}
}
private IIndexer<int, string> <>f__valuesIndexer;
public IIndexer<int, string> Values
{
get
{
if (<>f__valuesIndexer == null)
<>f__valuesIndexer = new <>c__DisplayClass1(this);
return <>f__valuesIndexer;
}
}
}
Но, конечно, в этом случае свойство действительно вернет IIndexer<int, string>
и не будет действительно индексированным свойством... Было бы лучше создать реальное свойство CLR, индексированное.
Как вы думаете? Вы хотите увидеть эту функцию на С#? Если нет, то почему?