Wiem, wiem ... Odpowiedź Erica Lipperta na tego typu pytanie brzmi zwykle mniej więcej w stylu: „ ponieważ nie było warto zaprojektować, wdrożyć, przetestować i udokumentować ”.
Mimo to chciałbym uzyskać lepsze wyjaśnienie ... Czytałem ten wpis na blogu o nowych funkcjach C # 4 , aw sekcji o COM Interop moją uwagę przykuła następująca część:
Nawiasem mówiąc, ten kod wykorzystuje jeszcze jedną nową funkcję: indeksowane właściwości (przyjrzyj się bliżej tym nawiasom kwadratowym po polu Zakres). Ale ta funkcja jest dostępna tylko dla współdziałania COM; nie można tworzyć własnych indeksowanych właściwości w C # 4.0 .
Dobrze ale dlaczego ? Wiedziałem już i żałowałem, że nie można utworzyć indeksowanych właściwości w C #, ale to zdanie skłoniło mnie do ponownego przemyślenia. Widzę kilka dobrych powodów, aby to wdrożyć:
- CLR to obsługuje (na przykład
PropertyInfo.GetValue
maindex
parametr), więc szkoda, że nie możemy tego wykorzystać w C # - jest obsługiwany w przypadku współpracy z COM, jak pokazano w artykule (przy użyciu dynamicznej wysyłki)
- jest zaimplementowany w VB.NET
- jest już możliwe tworzenie indeksatorów, tj. zastosowanie indeksu do samego obiektu, więc prawdopodobnie nie byłoby wielkim problemem rozszerzenie pomysłu na właściwości, zachowując tę samą składnię i zastępując po prostu
this
nazwą właściwości
Pozwoliłoby napisać takie rzeczy:
public class Foo
{
private string[] _values = new string[3];
public string Values[int index]
{
get { return _values[index]; }
set { _values[index] = value; }
}
}
Obecnie jedynym znanym mi obejściem jest utworzenie klasy wewnętrznej ( ValuesCollection
na przykład), która implementuje indeksator i zmiana Values
właściwości, tak aby zwracała instancję tej klasy wewnętrznej.
Jest to bardzo łatwe, ale irytujące ... Więc może kompilator mógłby to zrobić za nas! Opcją byłoby wygenerowanie klasy wewnętrznej, która implementuje indeksator i ujawnienie jej za pośrednictwem publicznego interfejsu ogólnego:
// 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;
}
}
}
Ale oczywiście w takim przypadku właściwość faktycznie zwróciłaby a IIndexer<int, string>
, a tak naprawdę nie byłaby właściwością indeksowaną ... Lepiej byłoby wygenerować rzeczywistą właściwość indeksowaną w środowisku CLR.
Co myślisz ? Czy chcesz zobaczyć tę funkcję w języku C #? Jeśli nie, dlaczego?