C# 4.0 umožňuje při používání COM API (pomoci COM interop) použít stejné syntaxe jako je u indexéru i pro tzv. indexed property (*). Viz například takovýto programový přístup k buňkám MS Excel sheetu:
excel.Range["A1"].Value = "ID";
Kromě COM interopu toto jazyk C# jinak neumožňuje. To je z toho důvodu, že C# zastává filozofii, že indexér je součástí objektu (který kromě něho může mít další čteny jako vlastnost Count nebo může implementovat IEnumerable apod.) a vlastnost pouze vrací takovýto objekt. V zásadě se tímto postojem dá souhlasit, já osobně s ním také nemám nejmenší problém.
Přesto pokud by jsme ve specifickém případě potřebovali “nasimulovat” jednoduchou indexed property resp. tedy vytvořit vlastnost, která bude vracet jednoduchý objekt obsahující pouze indexér, můžeme na to jít následovně.
Nejprve si připravíme pomocnou generickou třídu IndexedProperty<TKey, TValue>, obsahující právě jen indexér:
/// <summary>
/// Hodnota typu <typeparamref name="TValue"/> indexovaná klíčem typu <typeparamref name="TKey"/>
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
internal sealed class IndexedProperty<TKey, TValue>
{
#region member varible and default property initialization
private readonly Func<TKey, TValue> Getter;
private readonly Action<TKey, TValue> Setter;
#endregion
#region constructors and destructors
internal IndexedProperty(Func<TKey, TValue> getter, Action<TKey, TValue> setter)
{
this.Getter = getter;
this.Setter = setter;
}
#endregion
#region property getters/setters
/// <summary>
/// Indexér pro vrácení nebo nastavení hodnoty pro hodnotu klíče <paramref name="key"/>
/// </summary>
/// <param name="key">Klíč</param>
/// <returns>Hodnota odpovídající klíči <paramref name="key"/></returns>
public TValue this[TKey key]
{
get { return this.Getter(key); }
set { this.Setter(key, value); }
}
#endregion
}
Pomoci této třídy nyní můžeme delegovat kód vlastního getteru a setteru indexéru přímo do deklarace “indexované” vlastnosti. Vypadat to bude například následovně:
private readonly HashSet<string> m_Bools = new HashSet<string>();
public IndexedProperty<string, bool> Bools
{
get
{
return new IndexedProperty<string, bool>(
key => m_Bools.Contains(key),
(key, value) =>
{
if (value)
{
m_Bools.Add(key);
}
else
{
m_Bools.Remove(key);
}
});
}
}
private readonly Dictionary<string, int> m_Ints = new Dictionary<string, int>();
public IndexedProperty<string, int> Ints
{
get
{
return new IndexedProperty<string, int>(
key => m_Ints[key],
(key, value) => m_Ints[key] = value);
}
}
(*) Indexed property mohou také někteří znát například z “prastarého” a dnes již pravděpodobně zapomenutého jazyka Microsoft Visual Basic 6.0