Eu sei, eu sei ... A resposta de Eric Lippert para esse tipo de pergunta é geralmente algo como " porque não valeu o custo de projetar, implementar, testar e documentar ".
Mesmo assim, gostaria de uma explicação melhor ... Eu estava lendo esta postagem do blog sobre os novos recursos do C # 4 e, na seção sobre interoperabilidade COM, a seguinte parte me chamou a atenção:
A propósito, este código usa mais um novo recurso: propriedades indexadas (observe mais de perto os colchetes após Range). Mas esse recurso está disponível apenas para interoperabilidade COM; você não pode criar suas próprias propriedades indexadas em C # 4.0 .
OK mas porquê ? Eu já sabia e me arrependia de não ter sido possível criar propriedades indexadas em C #, mas essa frase me fez pensar novamente a respeito. Posso ver vários bons motivos para implementá-lo:
- o CLR suporta (por exemplo,
PropertyInfo.GetValue
tem umindex
parâmetro), então é uma pena que não possamos tirar proveito disso em C # - é compatível com interoperabilidade COM, conforme mostrado no artigo (usando envio dinâmico)
- é implementado em VB.NET
- já é possível criar indexadores, ou seja, aplicar um índice ao próprio objeto, então provavelmente não seria grande coisa estender a ideia para propriedades, mantendo a mesma sintaxe e apenas substituindo
this
por um nome de propriedade
Isso permitiria escrever esse tipo de coisas:
public class Foo
{
private string[] _values = new string[3];
public string Values[int index]
{
get { return _values[index]; }
set { _values[index] = value; }
}
}
Atualmente, a única solução alternativa que conheço é criar uma classe interna ( ValuesCollection
por exemplo) que implemente um indexador e alterar a Values
propriedade para que ela retorne uma instância dessa classe interna.
Isso é muito fácil de fazer, mas irritante ... Então, talvez o compilador possa fazer isso por nós! Uma opção seria gerar uma classe interna que implemente o indexador e expô-la por meio de uma interface genérica pública:
// 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;
}
}
}
Mas é claro que, nesse caso, a propriedade retornaria realmente um IIndexer<int, string>
e não seria realmente uma propriedade indexada ... Seria melhor gerar uma propriedade indexada CLR real.
O que você acha ? Você gostaria de ver esse recurso em C #? Se não, por quê?