クラスのプロパティを公開する際に、外部から変更されたくない場合にgetアクセサを用いると思いますが、
その公開している型が参照型であった場合、一見変更できないように見えて、バリバリ変更できてしまっている状態になっています。
sample.cs
//外部から変更不可
readonly string s;
public string S
{
get
{
return s;
}
}
//外部から変更可能
readonly List<string> str;
public List<string> Str
{
get
{
return str;
}
}
このStrに対して、外部から要素を追加削除変更し放題になっています。
そこで、登場するのが、ReadOnlyCollection、ReadOnlyDictionaryなどの読み取り専用クラスになります。
使い方は簡単、これらのインスタンスを生成する際に、引数に読み取り専用としたいコレクションを指定するだけ。
sample.cs
readonly List<string> str = new List<string>();
public ReadOnlyCollection<string> Str
{
get
{
return new ReadOnlyCollection<string>(str);
}
}
readonly Dictionary<string, string> dict = new Dictionary<string, string>();
public ReadOnlyDictionary<string, string> Dict
{
get
{
return new ReadOnlyDictionary<string, string>(dict);
}
}
ちなみに、List strの変更は、ReadOnlyCollection Strにも反映されます。
つまるところ、ReadOnlyCollection StrはただのList strの(List strの参照を保持している)ラッパークラスということですね。
ただし、コレクションの要素に参照型が入っていれば同じことになるので、気をつけましょう。
sample.cs
//Tが参照型の時、コレクション自体は変更できないが、
//要素のインスタンス(Tクラス)内部を変更可能
readonly List<T> str = new List<T>();
public ReadOnlyCollection<T> Str
{
get
{
return new ReadOnlyCollection<T>(str);
}
}
これで、スティーブジョブズ級のコントロールが、容易に実現できるかも!?