Indexed property

Tomáš Holan       18. 6. 2012       C#       5438 zobrazení

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

 

hodnocení článku

0       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback