Я знаю, я знаю ... Відповідь Еріка Ліпперта на подібне запитання, як правило, виглядає приблизно так: " тому що це не коштувало витрат на проектування, впровадження, тестування та документування цього ".
Але все-таки я хотів би отримати кращі пояснення ... Я читав цю публікацію в блозі про нові функції C # 4 , і в розділі про COM Interop привернула мою увагу наступна частина:
До речі, цей код використовує ще одну нову функцію: індексовані властивості (уважніше розгляньте ці квадратні дужки після Range.) Але ця функція доступна лише для взаємодії COM; ви не можете створити свої власні індексовані властивості в C # 4.0 .
Добре, але чому? Я вже знав і шкодував, що неможливо створити індексовані властивості в C #, але це речення змусило мене ще раз задуматися над цим. Я бачу кілька вагомих причин для його реалізації:
- CLR підтримує це (наприклад,
PropertyInfo.GetValue
маєindex
параметр), тому шкода, що ми не можемо цим скористатися в C # - він підтримується для взаємодії 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;
}
}
}
Але, звичайно, у такому випадку майно фактично поверне aIIndexer<int, string>
, а насправді не було б індексованим властивістю ... Краще було б створити справжнє індексоване властивість CLR.
Що ти думаєш ? Ви хотіли б бачити цю функцію в C #? Якщо ні, то чому?