2012-03-08 45 views
14

我在C#中重载了lessthan运算符,我想知道是否需要检查null。下面你可以找到一个例子:需要重载运算符<和空检查

public static bool operator <(MyClass x, MyClass y) 
{ 
    if (x == null && y == null) 
    { 
    return false; 
    } 
    if (x == null) 
    { 
    return true; //false? 
    } 
    if (y == null) 
    { 
    return false; //true? 
    } 
    return x.Value < y.Value; 
} 

或者,这是正确的:

public static bool operator <(MyClass x, MyClass y) 
{ 
    return x.Value < y.Value; 
} 

我didn't找到关于此的任何指令。但也许我错过了一些东西。

回答

12

答案取决于您的预期使用模式。如果您打算在混合中使用空值,并且您希望null值小于非空值,那么您的实现是正确的;如果您想要将null的值设置为大于非空对象,则应改为使用注释的返回值(falsetrue)。如果你不打算允许混合使用空值,那么抛出ArgumentNullException或允许NullReferenceException将是正确的选择。

+1

抛出'ArgumentNullException'小孩,永远不会抛出故意的'NullReferenceException'。 – Dagrooms 2017-05-04 20:31:40

+0

这就是“我打算这样做”和“哎呀”之间的区别。“ – Dagrooms 2017-05-04 20:31:58

1

自定义运算符不过是一种静态方法。而且,将军们通常不应该抛出异常。这意味着如果MyClass是引用类型,则需要这些空值检查。

顺便说一句,这是传统的nulls小于非nulls,这使得你提出的实现惯用。

+0

第一个参数怎么可以为空? – vulkanino 2012-03-08 13:41:44

+0

或者你只是让系统抛出,没有任何伤害(除了异常稍微不合适)。 – 2012-03-08 13:42:00

+0

@vulkanino:第一个参数可以为null,因为操作符是作为静态方法实现的。 – Ani 2012-03-08 13:44:24

2

就我个人而言,如果xynull,我应该抛出一个ArgumentNullException,这应该是一种特殊情况。

+5

'NullReferenceException'不应该从用户代码中抛出,这意味着有一个编程错误。改用'ArgumentNullException'。 – asawyer 2012-03-08 13:41:28

+0

@asawyer刚刚编辑;) – mdm 2012-03-08 13:42:17

+0

@asawyer'ArgumentNullException'也表示一个编程错误。我不确定两者都是这个框架的明智决定。 – 2012-03-08 13:42:52

4

两种方法都是正确的(对于不同的正确值)。

如果xy很可能为空,并且在您的情况下具有有效含义,那么请采用第一种方法。

如果xy非常不可能是空的,那么就去第二个,让任何异常传播到调用代码进行处理。

-1
  1. 这是一个坏主意,重载运算符类上。虽然结构可以。

  2. 如果您决定让某个班级的操作员超负荷运行,您需要:
    a。在您的逻辑中包含空值检查
    b。如果在
    中传递null时抛出异常c。不要空检查,并允许NullReferenceException异常(坏)

基本上,这是一个坏主意,重载操作上的一类。我会把你的类变成一个结构体,或者只是实现一个接口,比如IComparable<T>/IEquatable<T>,它在空值用于比较时有指导。

+0

我不同意这种观点 - 通常有价值的类是有意义的,特别是因为.NET中的相关(有用的)指南说”如果有疑问,写一个类“ – 2012-03-08 13:50:51

+0

这是一个糟糕的想法一个类是一个值,它可以与其他值进行比较,一个类是一个引用,不应该像结构一样对待,我还没有看到任何需要重载一个类的运算符(如 – 2012-03-08 14:01:01

+1

标准示例:复杂类,难道你不会超载运算符吗? – vulkanino 2012-03-08 14:03:09