2011-01-31 3 views
1

Каков предпочтительный способ проверки, является ли значение null?C# - Методы нулевой проверки

Скажем, у нас есть объект, который имеет свойства, которые могут быть null(некоторые из них или все из них).

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

ли вы использовать простую Entity.Property != null проверки в этом случае или вы бы реализовать конкретный метод, скажем, как

bool HasProperty() { 
    return Property != null; 
} 

Что бы вы выбрали и почему?

ответ

3

Для значений свойств, которые могут быть null, мое предпочтение сделать следующее

  1. Имеют свойство, содержащее значение, которое может быть возможно null
  2. ли еще одно свойство с префиксом Has и остальные, содержащий оригинальное название собственности, которое определяет, является ли другое имущество не нулевым.
  3. Добавить подтверждение в первоначальное состояние, если оно получено, если null

В этом примере было бы

SomeType Property { 
    get { 
    Contract.Requires(HasProperty); 
    return _property; } 
} 

bool HasProperty { 
    get { return _property != null; } 
} 

Смысл этого в том, что C# не имеет стандартный способ описания, могут ли или нет значение быть нулевым. Существует множество различных конвенций и методов, доступных, но не стандартных. И не понимая семантики вокруг значения приводит к пропущенному null проверкам и в конечном итоге NullReferenceExceptions.

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

Другие решения Я пытался

  1. Ничего не делать: Это как раз терпит неудачу снова и снова
  2. Используя явное Maybe<T> или Option<T> типа в аромате F #. Это работает, но я нахожу, что получаю много отталкиваний от разработчиков, которые никогда не выполняли функциональное программирование, и это приводит к отказу от идеи полностью в пользу №1.
+0

@Martinho, это то, что я получаю для редактирования сообщения много раз. Исправлено: – JaredPar

+1

Похоже, что многое из этого, хотя и интересное, не имеет ничего общего с исходным вопросом. – Pedro

+0

Я удивлен, что это было отмечено как ответ. Браво! – Pedro

1

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

0

Я бы предпочел написать отдельный объект Has*, только если свойство автоинициализируется (т. Е. Просто получить его может вызвать, скажем, пустую коллекцию, которая будет выделена), и это делает разницу в производительности. Если получить свойство дешево (как и должно быть, в некоторых случаях вы просто не можете помочь, если это имеет значение, хотя), нет необходимости в избыточном методе Has. не

Так что не имеет для общего случая:

public string Foo { get; set; } 

Но в некоторых случаях это может быть хорошей идеей:

private List<string> someStrings = null; 

public List<string> SomeStrings { 
    get { 
     if (someStrings == null) 
      someStrings = new List<string>(); 
     return someStrings; 
    } 
} 

public bool HasSomeStrings { 
    get { return (someStrings != null && someStrings.Count > 0); } 
} 
+1

Это ... ужасно. 'derp.SomeStrings.Count> 0' - единственное правильное решение в этом случае. В вашей собственности будет указано, что есть некоторые строки, когда на самом деле это фактически указывает, что доступ к ресурсу был получен хотя бы один раз. В нем ничего не говорится о том, содержит ли коллекция какие-либо строки. – Will

+0

@Will: Ну, кажется, я забыл счетный тест из свойства Has. Вы могли бы просто уйти и отредактировать его на все, что мне нужно, но спасибо, что указали это. –

+0

Эх, я бы предпочел ничто. Помогает сохранить мою самодовольную квоту. – Will

0

я проверяю только против null, потому что каждый обнуляемым тип делает внутренне точно так, как вы описали (но внутренний метод называется HasValue вместо HasProperty):

http://msdn.microsoft.com/de-de/library/b3h38hb0.aspx

0

Если свойство является тем, что не является общедоступным, тогда вам понадобится такой метод, как HasProperty(). Кроме того, если вы реализуете свой «nullness» по-другому, было бы неплохо иметь метод HasProperty().

1

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

«Эй, не проверить, если свойство имеет нулевое значение, используйте [имя] Свойство Null свойство»

Мм, нет.

+0

Если все, что вы делаете, это новое имя для нулевой проверки, да, это бессмысленно. Но если вы делаете что-то вроде Jared и не получаете свойство * немедленно *, если вы вызываете getter, когда оно равно null, вы действительно делаете это проще. NullReferenceExceptions имеют тенденцию проявлять слишком далеко от своей основной причины, но если вы потерпите неудачу быстро, как предлагает Джаред, они проявляются гораздо ближе, делая отладку менее болезненной. –

+0

@ Мартин, это запах кода. Свойства должны вести себя как можно больше полей. Если ваше свойство, как ожидается, генерирует исключение в определенных ситуациях, оно должно быть реорганизовано в метод. – Will

+0

Это хороший совет. Но есть ситуации, когда это оправданно бросать, даже из геттеров. Посмотрите на 'Stream.Length': он выдает, если' Stream.CanSeek' возвращает false. –

0

Нуль не обязательно плохой. Я думаю, все зависит от , почему вам нужно проверить, нет ли null, чтобы определить , как вам стоит его проверить.

Смежные вопросы