С# - Эта проверка необходима "obj is Person && 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 выражение выражает true, если предоставленное выражение не является нулевым, и предоставленный объект может быть добавлен к предоставленному типу, не вызывая исключения.

Я думаю, что дополнительная проверка для 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

Ответ 1

Мое предпочтение было бы использовать ключевое слово as.

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

Преимущество заключается в том, что позже в методе у вас есть типизированный экземпляр (objectToCompare), с помощью которого можно выполнять сравнения.

Вы правильно указали, что obj is Person вернет false, если obj не является производным от Person или obj имеет значение null и, следовательно, obj is Person && obj != null является избыточным; вам нужен только obj is Person, если вы используете этот стиль. Технически, может быть дробное увеличение производительности, сначала проверив нулевое значение, но коэффициент усиления будет незначительным.

Ответ 2

Функционально это правильно, но быстрее проверить значение null, чем проверять тип выполнения, поэтому вам лучше сначала проверить нулевой приоритет в большинстве ситуаций. Таким образом, если obj равно null, накладные расходы на проверку типа времени выполнения не будут понесены.

Ответ 3

Ваша версия выглядит более корректно для меня. Он не будет Человеком, если он не равен null, поэтому obj!= Null является избыточным.

Ответ 4

Ссылка на человека по-прежнему может быть нулевой ссылкой, поэтому технически да, требуются обе проверки.

Мне нравится мнение Томаса о том, как обрабатывать обе проверки сразу. null as MyClass == null и myClassInstance as OtherClass == null, поэтому при одной проверке объекта с безопасным литьем вы подтвердили оба условия, и, как он сказал, у вас есть строго типизированная ссылка для работы с этого момента.

Существует интересное обсуждение различий на низких уровнях между операциями ключевого слова is и as. Google "Как есть или есть как" (в настоящее время у меня проблема с Интернетом). Оказывается, они работают очень точно на уровне IL.