インデクサ

C#では、配列やディクショナリのようにインデックスによってアクセス可能なクラスを定義できる。

class Indexer
{
    Dictionary<int, String> innerDic = new Dictionary<int, string>();

    // this[インデックスとなる引数] で定義
    public string this[int i]
    {
        get { return innerDic[i]; }
        set { innerDic[i] = value; }
    }

    // インデックスは数値以外でもOK
    public string this[string s]
    {
        get { return this[int.Parse(s)]; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Indexer indexer = new Indexer();

        indexer[1] = "hoge";
        // 配列、Dictionaryのようにアクセス
        Console.WriteLine(indexer[1]); // hoge
        Console.WriteLine(indexer["1"]); // hoge
    }
}

下記のように、Dictionaryをラップして、ちょっとした制限加えるってのは結構使う場面はあるかも。

// 初回に設定された値が常に保持されるDictionary
class OneTimeDictionary<TKey, TValue>
{
    private Dictionary<TKey, TValue> _innerDictionary = new Dictionary<TKey, TValue>();

    public TValue this[TKey key]
    {
        get
        {
            return _innerDictionary[key];
        }
        set
        {
            if (!_innerDictionary.ContainsKey(key)) {
                _innerDictionary[key] = value;
            }
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        OneTimeDictionary<string, string> dic = new OneTimeDictionary<string,string>();

        dic["a"] = "1回目";
        dic["b"] = "1回目";
        dic["a"] = "2回目"; // これは反映されない

        System.Console.WriteLine("a:{0}", dic["a"]); // a:1回目
    }
}