.NET におけるプロパティは「まるで値」だが、実体はメソッドである。そのため 2 度続けて同じプロパティを取得した場合、1 度目と 2 度目で違う値が返される場合がある。
C#
Clazz obj = new Clazz();
int i1 = obj.Property;
int i2 = obj.Property;
if(i1 != i2){
// ここに処理がくる。
}
しかし、プロパティの実体がメソッドであったとしても「まるで値」のように振舞うべきなのがプロパティである。2 度続けて同じプロパティを取得したとき(対象のオブジェクトの他のプロパティやメソッドの呼び出しを間に挟まない)は必ず同じ値が返されるべきである。
つまり、
C#
obj.Property == obj.Property;
が False になるクラスを実装する事は可能だが、混乱するのでルールとしては正しくない。
…のだが、プロパティの型が参照型の場合もこのルールは正しいと言えるだろうか。
「等しい」という概念が意味を持たないクラスは、Object.Equals メソッドをオーバーライドしないのが普通だ。
C#
class Clazz{
public object Property{
get{
return new object();
}
}
}
上記のようなクラスの場合、
C#
Clazz obj = new Clazz();
obj.Property == obj.Property;
は、False になる。しかし、「同じ値」が取得できているとも言える。一体、何が正しいのか? ここで独断と偏見でプロパティのルールを定義する。
プロパティのルール
- 2 度続けて同じプロパティを取得した場合、同じ値が取得できる事を期待できる。
- 同じ値とは Equals(及び== 演算子) の結果が True となるもの。
としよう。このルールに則ったとすると、
- プロパティが新しいインスタンスを作って返すときは、その型は必ず Equals がオーバーライド( 及び == 演算子がオーバーロード)されているべき。
- それ以外は、プロパティは新しいインスタンスを作って返すべきではない。
結局
C#
Clazz obj = new Clazz();
obj.Property == obj.Property;
とした場合、必ず True になるものがプロパティとして正しいものと言える。それ以外はメソッドにすべきだ。
静的なプロパティは例外として良い(かもしれない)。