2011-02-25 31 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)); } 
}