2014-04-21 14 views
9

在C#中爲什麼Double覆蓋==Int32沒有,並且有什麼影響?爲什麼在System.Double中重寫==而在System.Int32中不重寫,以及它的後果是什麼?

我看看msdn庫。

我看到這雙鏈接不說太多here(雖然我明白雙重對於Double對象的簡寫)..它不顯示例如方法..

但這個鏈接System.Double確實提到了我在找的東西here

它顯示了Equality運算符正在使用雙打,因此重載。

圖像在MSDN Double,那麼方法(詳情字段之前),這表明運營商,它顯示了平等運算符重載

enter image description here

,我可以「運營商」下單擊平等和it says

public static bool operator ==(
    double left, 
    double right 
) 

而當我看System.Int32 圖像在MSDN Int32低於

enter image description here

見該圖像中,(爲System.Int32頁),它看起來像==不覆蓋。

爲什麼,這是什麼影響?

+1

它幾乎看起來像文檔是不完整的或有幕後的東西,因爲從文檔頁面它說:「Int32類型支持標準的數學運算,如加法,減法,除法,乘法,否定和一元與其他整型類型一樣,Int32類型也支持按位AND,OR,XOR,左移和右移運算符 可以使用標準數字運算符來比較兩個Int32值,也可以調用CompareTo或等於方法。「 –

+0

@TyCobb使用ILSpy發佈該帖子的人表明,該方法存在,所以可能表明它不是生成代碼..他也建議它反編譯。而且,我不懷疑它稱之爲Equals方法,但你能引用什麼來表明這一點? – barlop

+0

@TyCobb看着Matt發佈的信息。第一個和第三個WriteLine()給出了不同的結果。所以==和.Equals行爲不一樣。所以,==不調用'.Equals(..)',同意? – barlop

回答

-1

使用ILSpy我可以看到Double.Equals有一些額外的邏輯來檢查被比較的任一值是否爲NaN。

ILSpy也反編譯的==身體此:

public static bool operator ==(double left, double right) 
{ 
    return left == right; 
} 

的其它運營商遵循相同的模式,這是很奇怪。也許是反編譯錯誤?

+0

當源代碼可用時,無需使用ILSpy http://referencesource.microsoft.com/#mscorlib/system/double.cs#1a65cbdb09544ba1 –

+0

+ 1包含==方法的來源 – barlop

+0

@ Nighthawk441:在這種情況下不是,但總的來說ILSpy具有一些有用的導航和分析功能。它比使用網站更快。 :) – Artfunkel

3

一個可能的原因是因爲Double.NaN。

對於== operator:MSDN說:如果通過使用相等運算符(==)測試兩個Double.NaN值是否相等,則結果爲false;兩個Double.NaN值不被認爲是相等的。如果通過調用Equals方法測試它們是否相等,則結果爲真。當您想要確定Double的值是否不是數字(NaN)時,另一種方法是調用IsNaN方法。

因此,==運算符和Double的Equals方法對Double.NaN有不同的行爲,我認爲這是爲什麼==是爲double覆蓋。至於int,沒有這種特殊情況。

的代碼演示的差異:

using System; 

public class Example 
{ 
    public static void Main() 
    { 
     Console.WriteLine("NaN == NaN: {0}", Double.NaN == Double.NaN); 
     Console.WriteLine("NaN != NaN: {0}", Double.NaN != Double.NaN); 
     Console.WriteLine("NaN.Equals(NaN): {0}", Double.NaN.Equals(Double.NaN)); 
     Console.WriteLine("! NaN.Equals(NaN): {0}", ! Double.NaN.Equals(Double.NaN)); 
     Console.WriteLine("IsNaN: {0}", Double.IsNaN(Double.NaN)); 

     Console.WriteLine("\nNaN > NaN: {0}", Double.NaN > Double.NaN); 
     Console.WriteLine("NaN >= NaN: {0}", Double.NaN >= Double.NaN); 
     Console.WriteLine("NaN < NaN: {0}", Double.NaN < Double.NaN); 
     Console.WriteLine("NaN < 100.0: {0}", Double.NaN < 100.0); 
     Console.WriteLine("NaN <= 100.0: {0}", Double.NaN <= 100.0); 
     Console.WriteLine("NaN >= 100.0: {0}", Double.NaN > 100.0); 
     Console.WriteLine("NaN.CompareTo(NaN): {0}", Double.NaN.CompareTo(Double.NaN)); 
     Console.WriteLine("NaN.CompareTo(100.0): {0}", Double.NaN.CompareTo(100.0)); 
     Console.WriteLine("(100.0).CompareTo(Double.NaN): {0}", (100.0).CompareTo(Double.NaN)); 
    } 
} 
// The example displays the following output: 
//  NaN == NaN: False 
//  NaN != NaN: True 
//  NaN.Equals(NaN): True 
//  ! NaN.Equals(NaN): False 
//  IsNaN: True 
//   
//  NaN > NaN: False 
//  NaN >= NaN: False 
//  NaN < NaN: False 
//  NaN < 100.0: False 
//  NaN <= 100.0: False 
//  NaN >= 100.0: False 
//  NaN.CompareTo(NaN): 0 
//  NaN.CompareTo(100.0): -1 
//  (100.0).CompareTo(Double.NaN): 1 

代碼還爲MSDN

+0

你能給出任何可編譯的代碼示例來證明這種差異嗎? – barlop

+0

@TyCobb http://referencesource.microsoft.com/#mscorlib/system/double.cs#155似乎沒有提供任何有用的理由來覆蓋==雖然 –

+0

,而該解釋解釋公共布爾等於(雙obj)被覆蓋(因爲正文提到NaN),它不能解釋爲什麼公共靜態布爾運算符==被覆蓋,因爲該==方法的主體沒有提到NaN。我在問==方法。迄今爲止,TyCobb的理論似乎最爲強烈。 – barlop

1

Int32似乎是非常特殊的.NET中的條款。源代碼中缺少的功能很可能已納入系統的核心。

如果不在結構體中聲明這些運算符,則無法將結構體/值類型與==,>等進行比較。由於Int32缺失,我得出上述結論。

做一個簡單的測試和傾倒IL,他們做了完全相同的比較,沒有CompareToEquals被調用(我認爲實際發生了,我學到了一些東西!)。

public void TestInts() 
{ 
    var x = 1; 
    var y = 2; 
    var equals = x == y; 
} 

.method public hidebysig 
    instance void TestInts() cil managed 
{ 
    // Method begins at RVA 0x2094 
    // Code size 11 (0xb) 
    .maxstack 2 
    .locals init (
     [0] int32 x, 
     [1] int32 y, 
     [2] bool equals 
    ) 

    IL_0000: nop 
    IL_0001: ldc.i4.1 
    IL_0002: stloc.0 
    IL_0003: ldc.i4.2 
    IL_0004: stloc.1 
    IL_0005: ldloc.0 
    IL_0006: ldloc.1 
    IL_0007: ceq 
    IL_0009: stloc.2 
    IL_000a: ret 
} 

public void TestDoubles() 
{ 
    var x = 1.7d; 
    var y = 1.5d; 
    var equals = x == y; 
} 
.method public hidebysig 
    instance void TestDoubles() cil managed 
{ 
    // Method begins at RVA 0x20ac 
    // Code size 27 (0x1b) 
    .maxstack 2 
    .locals init (
     [0] float64 x, 
     [1] float64 y, 
     [2] bool equals 
    ) 

    IL_0000: nop 
    IL_0001: ldc.r8 1.7 
    IL_000a: stloc.0 
    IL_000b: ldc.r8 1.5 
    IL_0014: stloc.1 
    IL_0015: ldloc.0 
    IL_0016: ldloc.1 
    IL_0017: ceq 
    IL_0019: stloc.2 
    IL_001a: ret 
} 

上面的IL只是標準的ceq opcode呼籲這兩種情況。按照.NET標準,Int32應該有在源代碼中聲明的比較運算符,但它沒有。

編輯:看起來好像所有的整數值類型都是這樣的。 Single,Double,Decimal都有源代碼中指定的運算符。 Int16,Int32,Int64,Byte,不。

+0

http://stackoverflow.com/questions/3787294/where-are-operators-defined-in-c – barlop

+0

@barlop這是類似的。唯一的答案就是答案是指在價值類型方面沒有意義的參考平等。 – TyCobb

+0

我認爲你的評論回答了我的問題的原因(你的強有力的理論是好的)。並且你早前只發表了我的問題(你刪除了),如果我記得的話,暗示(沒錯)沒有任何分歧。 (你之所以刪除它,是因爲在你的回答中,你錯誤地提出了關於.equals的聲明)。但最終它是來自人們的評論(包括你刪除的那個,雖然現在很難檢查,但可能是第一個!),這回答了我的問題。 – barlop

相關問題