テーブル駆動方式とは、コード・コンプリートで紹介されている実装方法で、データの組み合わせを配列等であらかじめ定義しておくことで、ロジックをシンプルにすることができる方法です。
テーブル駆動方式の解説は省略しますが、C# ではどのような実装方法があるか試してみました。
尚、実行速度は考慮していません。
Dictionary を入れ子にする
まず最初に思いついたのがこれです。
enum HogeKey
{
Key1, Key2, Key3, Key4
}
enum PiyoKey
{
Key1, Key2, Key3, Key4
}
public static void Main()
{
var foo = new Dictionary<HogeKey, Dictionary<PiyoKey, string>>()
{
{
HogeKey.Key1, new Dictionary<PiyoKey, string>
{
{ PiyoKey.Key1, "Hoge1Piyo1"},
{ PiyoKey.Key2, "Hoge1Piyo2"}
}
},
};
Console.WriteLine(foo[HogeKey.Key1][PiyoKey.Key1]);
}
個人的には、初期化子はインデクサーを使って書く方が、Key
と Value
の対比が見やすくなるので好きです。
var foo = new Dictionary<HogeKey, Dictionary<PiyoKey, string>>()
{
[HogeKey.Key1] =
{
[PiyoKey.Key1] = "Hoge1Piyo1",
[PiyoKey.Key2] = "Hoge1Piyo2"
}
};
タプルを使う
テーブルが多次元であれば、Dictionary
より Tuple
のほうがネストが浅くなって良いかもしれません。
enum HogeKey
{
Key1, Key2, Key3, Key4
}
enum PiyoKey
{
Key1, Key2, Key3, Key4
}
public static void Main()
{
var foo = new Dictionary<Tuple<HogeKey, PiyoKey>, string>()
{
{
new Tuple<HogeKey,PiyoKey>(HogeKey.Key1, PiyoKey.Key1),
"Hoge1Piyo1"
},
{
new Tuple<HogeKey,PiyoKey>(HogeKey.Key1, PiyoKey.Key2),
"Hoge1Piyo2"
},
};
Console.WriteLine(foo[new Tuple<HogeKey, PiyoKey>(HogeKey.Key1, PiyoKey.Key1)]);
}
こちらも、インデクサーとタプルのシンタックスシュガーを使えば以下のように簡単に書けます。
var foo = new Dictionary<(HogeKey, PiyoKey), string>()
{
[(HogeKey.Key1, PiyoKey.Key1)] = "Hoge1Piyo1",
[(HogeKey.Key1, PiyoKey.Key2)] = "Hoge1Piyo2"
};
Console.WriteLine(foo[(HogeKey.Key1, PiyoKey.Key1)]);
JSON を使う
テーブルのデータを JSON ファイルで用意する方法です。
デシリアライズする手間とかはありますが、データとロジックが完全に分離されるので、結構良いと思います。
個人的な結論
- 階層構造を明確に表現したい場合は
Dictionary
- 複合主キーのように使いたい場合は
Tuple
- データを変更することがある場合は
JSON
が良いかなぁと思っています。