投稿数 - 437, コメント - 59540, トラックバック - 156

.NET - 2 度続けて同じプロパティを呼び出した場合に期待する事

.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 になる。しかし、「同じ値」が取得できているとも言える。一体、何が正しいのか? ここで独断と偏見でプロパティのルールを定義する。

プロパティのルール

  1. 2 度続けて同じプロパティを取得した場合、同じ値が取得できる事を期待できる。
  2. 同じ値とは Equals(及び== 演算子) の結果が True となるもの。

としよう。このルールに則ったとすると、

  1. プロパティが新しいインスタンスを作って返すときは、その型は必ず Equals がオーバーライド( 及び == 演算子がオーバーロード)されているべき。
  2. それ以外は、プロパティは新しいインスタンスを作って返すべきではない。

結局

C#

Clazz obj = new Clazz();
obj.Property == obj.Property;

とした場合、必ず True になるものがプロパティとして正しいものと言える。それ以外はメソッドにすべきだ。

静的なプロパティは例外として良い(かもしれない)。

投稿日時 : 2007年12月25日 13:02

フィードバック

# re: .NET - 2 度続けて同じプロパティを呼び出した場合に期待する事

これに従うとStopWatchの経過時間取得はメソッドでなくてはならんわけですな。
2007/12/25 13:36 | επιστημη

# re: .NET - 2 度続けて同じプロパティを呼び出した場合に期待する事

>これに従うとStopWatchの経過時間取得はメソッドでなくてはならんわけですな。

御意。すっげー変。

…と言いたいとこですが「時間と共に変化する事が目的」である StopWatch さんは、2回続けて値を取得しても「間に処理が入れられている」という事で対象外ではないかなと。

同様にマルチスレッド下での処理も。
2007/12/25 13:43 | 囚人

# re: .NET - 2 度続けて同じプロパティを呼び出した場合に期待する事

と思ったけど、StopWatch の経過時間取得はやっぱりメソッドの方が良いのか…。
ん~…。
2007/12/25 14:25 | 囚人

# re: .NET - 2 度続けて同じプロパティを呼び出した場合に期待する事

うーん、Clear, Start, Stop, Suspend メソッドを持ってたら
状態遷移と絡むと属性ではないような気がする。。。ような気がする。
参照することに意味があるかどうかということは関係ないかな?
2007/12/25 15:54 | まどか

# re: .NET - 2 度続けて同じプロパティを呼び出した場合に期待する事

>うーん、Clear, Start, Stop, Suspend メソッドを持ってたら
>状態遷移と絡むと属性ではないような気がする。。。ような気がする。
>参照することに意味があるかどうかということは関係ないかな?

すみません。ちょっと仰ってる事が理解できませんでした。
2007/12/25 23:29 | 囚人

コメントの投稿

タイトル
名前
URL
コメント