20978


int型とlong型で同じ数値を比較すると == はtrueを返しますが、Equalsはfalseを返すことがあります。

[code]

    Console.WriteLine("1 == 1L: {0}", 1 == 1L);
    Console.WriteLine("1L == 1: {0}", 1L == 1);
    Console.WriteLine("1.Equals(1L): {0}", 1.Equals(1L));
    Console.WriteLine("1L.Equals(1): {0}", 1L.Equals(1));
    
    // 出力：
    //   1 == 1L: True
    //   1L == 1: True
    //   1.Equals(1L): False
    //   1L.Equals(1): True
    
[/code]

値型では基本的に == と Equals は同じだと思っていたのですが、違うのでしょうか？

また、もしEqualsだけ型を厳密に見ていると仮定すると、trueを返すこともあるのが謎です。


CC BY-SA 3.0
2016-01-16T09:53:29.503
20976
2016-01-17T02:23:55.537
8000
question
c#
違う型の同じ数値を比較するときに == と Equals で結果が異なる？


`Object.Equals(object)`は型が同じであれば`operator ==(T,
T)`の結果を、型が異なれば`false`を返すのが標準的な動作です。  
しかし質問文の例ではオーバーロードにより`int`から`long`への暗黙変換が発生しており、コード上の型が一致していません。

最初の二つの式ですが、C#の数値比較は`int`、`uint`、`long`、`ulong`同士の比較しか定義されていないため、`operator
==(long, long)`が選択されます。  
また最後についても`IEquatable<T>`の実装である`Int64.Equals(long)`が存在するため、こちらも暗黙変換が発生します。  
これらの結果が`False`でないのはそのためです。


CC BY-SA 3.0
2016-01-16T10:41:54.547
20978
2016-01-16T10:58:53.557
2016-01-16T10:58:53.557
5750
5750
20976
answer


等値演算子の`==`に関しては、C# の言語仕様 **7.3.6.2 二項数値上位変換**
で規定されている通り、`int`が`long`へ暗黙の型変換されるためにtrueとなります。

他方、Equalsメソッドの呼び出しに関しては、pgrhoさんのご指摘の通りですが、多少補足しますと、`long.Equals(long
obj)`と、`long.Equals(object obj)`のどちらが **より適切** であるかは、C#の言語仕様 **7.5.3
オーバーロードの解決法** によって、 **より適切な関数メンバ** が解決されていくことになります。

この際、元の`int`は、`long`へも`object`へも暗黙の型変換が許容されていますので、どちらがより適切なのかと言うことになりますが、これは
**7.5.3.5 より適切な変換対象** より

> 異なる 2 つの型 T1 と T2 がある場合、次の条件が 1 つでも満たされると、T1 の方が T2 より適切な変換対象です。  
>  • T1 から T2 への暗黙の型変換が存在し、T2 から T1 への暗黙の型変換が存在しない  
>  以下略

とのことから、`long`から`object`への暗黙の型変換が存在し、逆に`object`から`long`への暗黙の型変換が存在しないことから、最終的に`long.Equals(long
obj)`がより適切な関数メンバと解釈され、適用されるので、

[code]

    Console.WriteLine("1L.Equals(1): {0}", 1L.Equals((long)1));
    
[/code]

明示的に書くのであれば、このような関数呼び出しなり、引数のi 及び lが同値で有れば、trueに成るのだと思います。

他方、int.Equalsの場合は、long型からint型への暗黙の型変換は存在せず、逆にlong型からobject型への暗黙の型変換は存在するので、結果的にint.Equals(object
obj)が呼ばれFalseに成るのだと思います。


CC BY-SA 3.0
2016-01-16T11:41:06.903
20981
2016-01-17T02:23:55.537
2016-01-17T02:23:55.537
7287
7287
20976
answer