2011-02-25 76 views
2

有沒有辦法在類上做到這一點,並仍然保留檢測Type變量是否爲null的能力?我可以爲結構體做這些事情(因爲結構體不能用null結構,而不是將x與null進行比較,所以使用單獨的方法caleld IsNull或HasValue ...但是不能將該技術與一流的事業,當類變量爲空,當然,你不能要求它這樣一個實例方法在類上覆蓋==和!=

public class myClass: IEquatable<myClass> 
{ 
    public int IntValue { get; set; } 
    public static bool operator ==(myClass cA, myClass cB) 
    { return cA is myClass && cB is myClass && cB.Equals(cA); } 
    public static bool operator !=(myClass cA, myClass cB) 
    { return !(cA == cB); }  
    public override bool Equals(object o) 
    { return o is myClass && this == (myClass)o; } 
    public override bool Equals(myClass o) 
    { return IntValue == o.IntValue; } 

} 

但是當我去!

myClass x; 
if (x != null) // this returns false when it should be true 
{ 
    //code to execute with x here 
} 

對於它的價值,唯一的我希望這是一個類的原因是因爲它參與了一個簡單的繼承關係,這是一個不可變的類,實際上我在這裏要做的是編碼它,因此它可以表現得像一個不可變的第二類可空,酷似一個不可改變的,可空結構的行爲(如Nullable<int>Nullable<float>

+0

只是在這裏大聲思考,但是當cA或cB爲空時,在您的超載中始終返回true的缺點是什麼? – 2011-02-25 14:45:07

+0

在'公共靜態布爾運算符==(myClass cA,myClass cB)'is'操作符調用{return cA myClass && cB is myClass && cB.Equals(cA); ''不需要。 – 2011-02-25 14:46:07

回答

5

這就是爲什麼IsNull應該是一個帶參數的靜態方法。 string.IsNullOrEmpty就是一個很好的例子。之後,沒有什麼能夠阻止你將其作爲擴展方法。

public class MyClass 
{ 
    public static bool IsNull(MyClass other) 
    { return ReferenceEquals(other, null); } 
    public static bool HasValue(MyClass other) 
    { return !IsNull(other); } 
    // other code 
} 

public static class MyClassExtension 
{ 
    public static bool IsNull(this MyClass myClass) 
    { 
     return MyClass.IsNull(myClass); 
    } 
} 

這將讓你做以下沒有拋出:

MyClass myClass = null; 
if(myClass.IsNull()) 
{ 
    //... 
} 
+0

從下面結合@jjrdk的ReferenceEquals建議,我認爲這會起作用。 。 謝謝! – 2011-02-25 14:52:56

+0

Coincoin:我編輯了你的答案以顯示完整的解決方案 – 2011-02-25 15:11:04

+0

哦!謝謝。我自己在做這件事時猶豫不決,所以我改爲+1。 :) 感謝你的接納。 – Coincoin 2011-02-25 20:02:17

3

如果你不初始化x所以它是null,你需要做的這個

myClass x = new myClass(); 
if (x != null) {/* is true */} 
+0

無論x是否爲空,寫入(x!= null)將調用我的運算符覆蓋中的代碼.... – 2011-02-25 14:52:18

+0

但這就是它返回false的原因,因爲它爲空... – Jimmy 2011-02-25 14:53:06

+0

添加了更多代碼這個明確的......但是'!='不是標準的.net'!='....它正在運行'!='的覆蓋。所以變量是否爲null與它無關。它是我的重寫中的代碼,它控制'!='方法將返回的內容。 – 2011-02-25 15:07:12

2
  1. 你不應該這樣做的。
  2. 如果你真的必須的話,你應該只對不可變類做這個。然後,
  3. 您應該遵循guidelines
+0

1)謝謝你的幫助。 2)我需要這樣做。 3)這種類型是不可變的。 4)按照你的指導方針留在你的箱子裏。 – 2011-02-25 14:51:13

1

爲什麼不重寫GetHashCode和equals? !

當你覆蓋它們都允許你這樣做一舉兩得==和=很容易..

3

您可以隨時使用:

ReferenceEquals(x, null) 

這將返回顯示x是否爲空一個布爾值。

+0

希望我可以檢查兩個答案作爲解決方案,您的答案,結合從下面的Coincoins最終成爲解決方案...謝謝 – 2011-02-25 15:09:06

2
public class myClass: IEquatable<myClass> 
{ 
    public static bool operator ==(myClass cA, myClass cB) 
    { return (cB == null && cA = null) || (cA is myClass && cB is myClass && cB.Equals(cA)); } 
}