Подтвердить что ты не робот

Где проверить, является ли объект нулевым или нет?

Где вы проверяете, является ли объект, который вы передаете методу, нулевым или нет?

Следует ли тестировать объект перед вызовом метода? или внутри метода, который использует аргумент?

public class Program
{
    public static void Main(string[] args)
    {
        // Check if person is null here? or within PrintAge?

        PrintAge(new Person { Age = 1 });
    }

    private static void PrintAge(Person person)
    {
        // check if person is null here?

        Console.WriteLine("Age = {0}", person.Age);
    }
}

public class Person
{
    public int Age { get; set; }
}

Наличие "нулевой" проверки в обоих классах кажется слишком избыточным.

[ИЗМЕНИТЬ]. Что было бы ошибкой в ​​проверке нуля в вызывающем или вызываемом абоненте?

[EDIT2]: я просто столкнулся с Defensive Programming и кажется, что он защищает проверку нулевого номера в пределах вызываемого абонента, Интересно, является ли это общепринятой практикой.

4b9b3361

Ответ 1

Вы можете создать метод для работы только с действительными объектами.

Это означает, что вы ожидаете получить действительные объекты (но не в вашем случае).
Это означает, что вы не знаете, как реагировать и что делать с недопустимыми объектами:

  • тихое возвращение из функции не является решением,
  • бросание исключения означает, что вы переводите ответственность на верхнюю методы, где они могут проверить значение уже до передачи вам.

Итак, если ваш метод не знает точно, как обрабатывать недопустимый объект, и метод не будет следовать дополнительной логике в неверном случае, вы должны положить

Debug.Assert( Person );

в начале PrintAge, и это будет заставлять вас делать проверки сверху стеком вызовов.

Более низкая функция в иерархии - это меньше проверок, которые она должна выполнять. Ниже приведены недостатки выполнения проверок в функциях, выполняющих работу.

  • Функция, выполняющая фактическую работу должен быть как можно более ясным без массы , если s
  • Функция будет вызываться более, чем много раз
  • Такая функция может вызывать такие функции, и они могут снова вызвать такие функции. Каждый из них будет выполнять ту же проверку

Ответ 2

Если вы создадите библиотеку, будут методы, открытые для внешнего мира. Вы должны проверить входящие данные в этих методах. Никакие проверки не требуются в методах, которые вы не раскрываете, потому что только ваш код вызывает их, и его логика должна обрабатывать все случаи, которые вы приняли в выставляемом методе.

                    --------------------------
                   |                          |
                   |         Library          |
                   |                          |
 -------        ---------        ----------   |
|       |      |         |      |          |  |
| Outer |      | Library |      | Library  |  |
|       | ===> | Entry   | ===> | Backend/ |  |
| World |      | Method  |      | Helpers  |  |
|       |      |         |      |          |  |
 -------        ---------        ----------   |
                   |                          |
                   |                          |
                    --------------------------

Если вы приняли предоставленные данные в методе ввода, вы должны выполнить запрошенное действие и вернуть ожидаемый результат, который обрабатывает все остальные случаи.

UPDATE

Чтобы очистить ситуацию внутри библиотеки. Там могут быть нулевые проверки, но только из-за логики, а не из-за проверки параметров. Есть две возможности для размещения нулевых проверок внутри библиотеки. Первый, если вызываемый метод знает, как обрабатывать нулевые значения.

private CallingMethod()
{
   CalledMethod(someData);
}

private CalledMethod(Object parameter)
{
   if (parameter == null)
   {
      // Do something
   }
   else
   {
      // Do something else
   }
}

И вторая ситуация, если вы вызываете метод, который не может обрабатывать нулевые значения.

private CallingMethod()
{
   if (someData == null)
   {
      // Do the work myself or call another method
   }
   else
   {
      CalledMethod(someData);
   }
}

private CalledMethod(Object parameter)
{
   // Do something
}

Вся идея состоит в том, чтобы отклонить случаи, с которыми вы не можете справиться, и обрабатывать оставшиеся случаи all должным образом. Если вход недействителен, вы генерируете исключение. Это заставляет вызывающего абонента предоставлять только допустимые значения и не позволяет вызывающему абоненту продолжать выполнение с бессмысленными возвращаемыми значениями (кроме того, что вызывающий объект помещает исключение, и продолжает).

Ответ 3

У вас нет ничего, чтобы проверить Main - вы используете оператор new, который никогда не возвращает null (кроме Nullable<T>).

Было бы вполне разумно проверить PrintAge, особенно если он был обнародован. (Для частных API это менее важно для проверки аргументов, но все равно может быть очень полезно.)

if (person == null)
{
    throw new ArgumentNullException("person");
}

В эти дни в С# 3.0 я обычно использую метод расширения для этого.

Ответ 4

Я бы сказал, что проверка n PrintAge, похоже, имела больше смысла, поскольку это выполняет контракт на рутину. Разумеется, вы могли бы заменить нулевые проверки кодом Debug.Assert() для проверки во время тестирования, но не во время выпуска.

Ответ 5

Вы имеете в виду проверку обоих методов? Я бы проверял в PrintAge точно, и если это имеет смысл и в Main. Я не думаю, что есть определенный ответ в целом. Это зависит: -)

Ответ 6

Обычно я допускаю, чтобы мои контрольные проверки проверялись моими ожиданиями; если я ожидаю, что что-то будет нулевым или я не уверен в этом, добавлю чек. В противном случае я этого не делаю. Исключения Nulllpointer являются одними из самых простых проблем для отслеживания, поэтому чрезмерное разбрызгивание кода чеков. В конкретном примере я ничего не проверил бы, потому что он интуитивно понятен не null.

Ответ 7

Что бы вы хотели сделать, если экземпляр null?

Я думаю, что это зависит от API, который вы предоставляете, и определяете контракт (как это делают классы framework.net). Сказав это, вам не нужно проверять значение null (в основном), если метод определяет ожидаемый результат в случае передачи нулевой ссылки.

Ответ 8

Существует только один случай, когда конструктор может вернуть null [ new() в Nullable<T>], поэтому код вызова не нужно проверять.

Вероятно, следователь должен проверить; выбрасывая ArgumentNullException, если он был нулевым. В .NET 4.0 это будет лучше обслуживаться кодовыми контрактами. Но еще нет; -p

Ответ 9

Как я понимаю ваш вопрос, он более общий, чем иллюстрированный вашим примером. Мои предпочтения таковы:

  • Все общедоступные методы должны проверять вход NULL и, при необходимости, генерировать исключения. Поэтому, если вы создаете инфраструктуру для других, используйте код в обороне.
  • Частные методы могут опускать проверку NULL, если вы знаете, что это делается в другом месте, или что аргументы никогда не будут NULL, но в целом я предпочитаю явное исключение ArgumentNullException для NullRefereceException.

Брэд Абрамс имеет здесь несколько дополнительных вкладок: http://blogs.msdn.com/brada/archive/2004/07/11/180315.aspx

Ответ 10

Резервный код не самый элегантный, но безопасный.

Это зависит от того, кем является ваш предполагаемый пользователь, если его вы тогда контролируете, как все используется, и проверки необходимы только в том случае, если вы не уверены в том, каково будет состояние ваших переменных.

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

Ответ 11

Определенно проверьте PrintAge, это правильное место для проверки. Он может быть избыточным, но никого не повредит, если вы его не выполняете 1000 раз в секунду. (В зависимости от проверки выкиньте исключение или исправьте его, если сможете)

Другая проверка зависит от вашего фактического потока, в этом примере у вас нет потока, поэтому я не могу прокомментировать этот бит. Но обычно рассматривайте свои параметры как испорченные.

Ответ 12

PrintAge должен быть методом для Person, а не статическим, принимающим параметр Person as. Не требуется проверка.

Проверка нулевых значений делает код излишне сложным. Структурируйте свой код, чтобы ограничить (или устранить) случаи, когда null является возможным значением, и вы будете иметь гораздо меньше проверок для записи.