2011-05-05 23 views
10

我看到了下面的代碼,C# - 這是檢查有必要「obj是人&& OBJ!= NULL」

public override bool Equals(object obj) 
{ 
    // From the book http://www.amazon.co.uk/Pro-2010-NET-4-0-Platform/dp/1430225491 
    // Page 254! 
    if (obj is Person && obj != null) 
... 
} 

根據我的理解,我認爲該代碼應被重寫如下:

public override bool Equals(object obj) 
{ 
    if (obj is Person) 
... 
} 

這是正確的嗎?

基於http://msdn.microsoft.com/en-us/library/scekt9xw%28v=vs.80%29.aspx

An是表達式評估爲真,如果所提供的表達爲非空,並且所提供的對象可以被強制轉換爲提供的類型而不會導致拋出異常。

我認爲額外檢查null是沒有必要的。換句話說,該代碼「obj!= null」根本不應該被打中。

謝謝

// //更新

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication2 
{ 
    class Employee 
    { 
     public static void CheckIsEmployee(object obj) 
     { 
      if (obj is Employee) 
      { 
       Console.WriteLine("this is an employee"); 
      } 
      else if (obj == null) 
      { 
       Console.WriteLine("this is null"); 
      } 
      else 
      { 
       Console.WriteLine("this is Not an employee"); 
      } 
     } 
    } 

    class NotEmployee 
    { } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      Employee e = new Employee(); 

      Employee.CheckIsEmployee(e); 

      Employee f = null; 
      Employee.CheckIsEmployee(f); 

      NotEmployee g = new NotEmployee(); 
      Employee.CheckIsEmployee(g); 
     } 
    } 
} 

輸出結果:

this is an employee 
this is null 
this is Not an employee 

回答

8

我的偏好是使用as關鍵字。

public override bool Equals(object obj) 
{ 
    var objectToCompare = obj as Person; 
    if (objectToCompare == null) 
     return false; 
    ... 
} 

的優點是,在後面的方法,你有一個類型化的實例(objectToCompare)與做你的比較。

如果obj不是從Person派生的,或者obj爲空,並且因此obj is Person && obj != null是多餘的,那麼您的評估中obj is Person將返回false是正確的;如果您使用該風格,則只需要obj is Person。從技術上講,通過首先檢查空值可能會有一小部分性能增益,但增益可以忽略不計。

+0

取決於'is'的定義是什麼;-)在.NET的情況下,as'在內部執行'is'並且如果'is'爲false,則將結果設置爲'null'。如果有時可能會出現'null',jlew的解決方案會更加優化。 – 2011-05-05 17:01:25

+0

@Eric J:D.使用'as'的原因主要是稍後使用類型化實例。因此,在jlew的解決方案中,你可能(可能)需要在確定它不是null之後將'obj'作爲'Person'來投射,這樣你才能完成Equals評估的其餘部分。保存相同結果的一行或兩行代碼。 – Thomas 2011-05-05 17:08:08

1

你的版本看起來更正確的我。它不會是一個人,除非它是非空的,所以obj!= null是多餘的。

8

功能上它是正確的,但檢查null比檢查運行時類型更快,所以最好在大多數情況下首先檢查null。這樣,如果obj 爲null,則不會產生運行時類型檢查的開銷。

+0

請看我更新的帖子。 – q0987 2011-05-05 17:03:22

+2

@ q0987,好吧,我只是做了一個快速的性能測試,結果表明兩種方法的性能基本相同。任何一種操作都可以每秒執行數億次,所以從性能的角度來看,這可能不值得擔心。 – jlew 2011-05-05 17:18:46

1

對Person的引用仍然可以是空引用,因此在技術上是肯定的,兩個檢查都是必需的。

我喜歡托馬斯的回答,以便如何同時處理兩項檢查。 null as MyClass == nullmyClassInstance as OtherClass == null,所以通過一次檢查安全鑄造對象,你已經確認了兩種情況,正如他所說的那樣,從那時起你就有了一個強類型的參考。

關於isas關鍵字操作之間的低級別差異有一個有趣的討論。谷歌「就像現在一樣」(我目前有互聯網問題)。事實證明,他們在IL級別的工作非常相似。

+1

+1爲了讓我查閱「是原樣還是原樣」。 http://blogs.msdn.com/b/ericlippert/archive/2010/09/16/is-is-as-or-is-as-is.aspx?PageIndex=2#comments – Thomas 2011-05-05 17:21:00

相關問題