風邪気味で思考力も落ちていて、仕事がはかどりません。
というわけで、こんな文章を書いてしまいます。
キーと値のペアを保持するコレクション §
プログラムを書いていて、ふと、キーと値のペアを複数保持する必要が発生しました。どちらも文字列です。
常識的には、キーと値のペアを保持するコレクションなら、Hashtableクラスの出番です。しかし、できれば、これを使いたくありません。なぜなら、Hashtableクラスは登録した順番を維持しないからです。たとえば追加を繰り返してデータを入れたとき、列挙させて追加した順番にデータが得られないわけです。もちろん、それはハッシュ値を使った高速アクセスのため、そのような仕様になっているのだとは思いますが。単体テストを書くことを考えると、順番が容易に予測できないことは、ちょっと不便です。つまり、テスト側で、順番に関係なく必要な値が全てあることをチェックしなければならないわけで面倒です。更に、URLのパラメータのように文字列になったものをチェックするなら、ちょっとやりたくないぐらい面倒が増えます。
順番を保持せよ §
もし、格納するデータ量が少なく、順番にアクセスすることしかしないなら、特にHashtableの高速性は不用です。
そこで、キーと値を保持するコレクションで、かつ、順番を維持するものが無いか調べてみました。すると、System.Collections.Specialized.NameValueCollectionというクラスが見つかりました。オブジェクトではなく、文字列のキーと値を使うので、Hashtableの代用品にはなりませんが、この場はこれでOKです。
しかし、リファレンスマニュアルを見ると、順番に関して特に説明がありません。はたして、順番を保持してくれるのだろうか、と思ってテストプログラムを書いてみました。
テストプログラム (C#による) §
using System;
class CollectionSample
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("NameValueCollectionで試すでやんす");
System.Collections.Specialized.NameValueCollection t1
= new System.Collections.Specialized.NameValueCollection();
t1.Add("xyz","XYZ");
t1.Add("def","DEF");
t1.Add("abc","ABC");
t1.Add("ghi","GHI");
foreach( string key in t1.Keys )
{
Console.WriteLine(key);
}
Console.WriteLine("Hashtableで試すですます");
System.Collections.Hashtable t2
= new System.Collections.Hashtable();
t2.Add("xyz","XYZ");
t2.Add("def","DEF");
t2.Add("abc","ABC");
t2.Add("ghi","GHI");
foreach( string key in t2.Keys )
{
Console.WriteLine(key);
}
}
}
前半はNameValueCollectionクラスで、後半はHashtableで同じように値を入れて、キーを順番に列挙させ表示させています。
実行結果 §
NameValueCollectionで試すでやんす
xyz
def
abc
ghi
Hashtableで試すですます
def
ghi
abc
xyz
見ての通り、結果は食い違っています。
NameValueCollectionを使うと追加した順番に列挙されていますが、Hashtableは同じではありません。
というわけで、順番を保持しながらキーと値のペア(文字列)を使う場合は、NameValueCollectionクラスが使えそうです。
ちょっとした後悔 §
しまった。
Viusal Basic.NETプログラマを応援する熱血ライターと名乗った割に、C#で書いてしまった…… (汗)
精進が足りませんね。