none
C#のdouble型のobject値の比較について RRS feed

  • 質問

  • object value1 = 0.0;
    object value2 = 0.0;
    Console.WriteLine(value1.GetType() == typeof(double));  // True
    Console.WriteLine((double)value1 == (double)value2);    // True
    Console.WriteLine(value1.Equals(value2));               // True
    Console.WriteLine(value1 == value2);                    // False

    一番最後の比較だけfalseになります。

    上二つの比較となにが違うのでしょうか?

    2013年8月16日 12:44

回答

  • object の == 演算子が内部でどのような処理をしているのかイマイチ判りません。

    言語仕様を知りたいのであれば、Visual Studio のインストール先の VC# フォルダーに Specifications というフォルダーがあるのでそちらを確認してください。
    手元の Visual Studio 2010 付属の文書でいくところの「7.10.6 参照型等値演算子」に該当します。

    object 型に double の値を入れた時点で ボックス化 されていますので、元の値型とは異なる存在(参照型)になっています。
    参照型の参照同士を比較した場合、異なる参照になるので False になるのは必然です。
    (object 型の == 演算子は、object.ReferenceEquals 相当と考えてよいでしょう)

    どちらもdouble型の値を持っているのだからdouble型の比較を行ってくれてもいいように思うのですが・・・

    そういう動作を希望する場合は、Equals メソッドを使ってください。
    (== 演算子はオーバーライドできませんし、現状の仕様は定義されている通りで変えられません)

    2013年8月16日 13:37

すべての返信

  • 最後は object 型同士の比較ですので、object の == 演算子の処理を呼び出しています。
    これは object 型の参照を比較する処理になるため、二つの参照は異なることから False になります。

    Equals は object 型で virtual で定義 されており、double 型で処理がオーバーライドされている と考えてください。
    (double)value1 == (double)value2 は double 型同士の比較なので、double 型の == 演算子が呼び出されます。

    ところで、ここは .NET Micro Framework を対象としたフォーラムですが、普通の PC 向けの .NET Framework ではなく、組み込み向けの .NET Micro Framework なのでしょうか?
    2013年8月16日 12:55
  • object の == 演算子が内部でどのような処理をしているのかイマイチ判りません。

    てっきり== 演算子の内部でEqualsが呼び出されているものと思っていました。

    どちらもdouble型の値を持っているのだからdouble型の比較を行ってくれてもいいように思うのですが・・・


    2013年8月16日 13:31
  • object の == 演算子が内部でどのような処理をしているのかイマイチ判りません。

    言語仕様を知りたいのであれば、Visual Studio のインストール先の VC# フォルダーに Specifications というフォルダーがあるのでそちらを確認してください。
    手元の Visual Studio 2010 付属の文書でいくところの「7.10.6 参照型等値演算子」に該当します。

    object 型に double の値を入れた時点で ボックス化 されていますので、元の値型とは異なる存在(参照型)になっています。
    参照型の参照同士を比較した場合、異なる参照になるので False になるのは必然です。
    (object 型の == 演算子は、object.ReferenceEquals 相当と考えてよいでしょう)

    どちらもdouble型の値を持っているのだからdouble型の比較を行ってくれてもいいように思うのですが・・・

    そういう動作を希望する場合は、Equals メソッドを使ってください。
    (== 演算子はオーバーライドできませんし、現状の仕様は定義されている通りで変えられません)

    2013年8月16日 13:37
  • 親切な回答ありがとうございます。

    試しにint型に変えてみても結果は同じでした...

    object同士の比較の場合はEqualsを使うようにします。

    2013年8月16日 14:04
  • どちらもdouble型の値を持っているのだからdouble型の比較を行ってくれてもいいように思うのですが・・・

    コンパイラはコンパイル時に記述された通りにコンパイルを行います。object型の変数にどのような値が入っていようとobject型として処理します。これは少し考えればすぐにわかる話です。

    object value1 = new Random().Next() < 1000 ? (object)100 : (object)100.0;

    こう書かれたらobject型変数に格納されるデータ型は実行時の乱数の結果によって変わるため、コンパイル時に決定することはできません。

    2013年8月18日 4:06