2011-05-05 71 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

相关问题