.NET DBNull против ничего по всем типам переменных? - PullRequest
6 голосов
/ 03 октября 2008

Меня немного смущают нулевые значения и переменные в .NET. (VB предпочтительно)

Есть ли способ проверить «пустоту» ЛЮБОЙ данной переменной независимо от того, был ли это объект или тип значения? Или моя нулевая проверка должна всегда предвидеть, проверяет ли она тип значения (например, System.Integer) или объект?

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

a) никогда не присваивалось значение с момента объявления

b) присвоено нулевое значение из объекта данных (который поступил из базы данных)

c) были установлены равными другому значению переменной, которое было нулевым

d) была установлена ​​переменная сеанса / приложения ASP.NET, которая никогда не задавалась или не имела срока действия.

Существуют ли общие рекомендации по обработке нулевых сценариев в .NET?

ОБНОВЛЕНИЕ: Когда я говорю о типе значения, являющемся «нулевым», я действительно имею в виду тип значения, который либо никогда не устанавливался, либо был в некоторой точке установлен равным или приведен из нулевого объекта ,

Ответы [ 6 ]

4 голосов
/ 03 октября 2008

Типы значений не могут быть нулевыми. Это нарушает то, что значит быть типом значения. Вы можете обернуть значения типов как Nullable (Of T), что дает вам большой набор методов, и проверки для ничего не работает. Но у вас много работы с этой оболочкой. Возможно, вы можете уточнить, что вы пытаетесь сделать?

Для полноты синтаксис VB для упаковщиков Nullable:

Dim i as Nullable(Of Integer) = Nothing '.NET 2.0/3.0'
Dim j as Integer? = Nothing '.NET 3.5'

EDIT: тип значения всегда предварительно инициализируется значением по умолчанию, 0 для чисел, false для логического значения и т. Д.

2 голосов
/ 03 октября 2008

Типы нормальных значений (логические, целые, длинные, поплавковые, двойные, перечислимые и структурные) не обнуляются.

Значением по умолчанию для всех типов значений является 0.

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

Кроме того, как отмечают другие, начиная с .net 2.0 появился новый универсальный тип с именем Nullable<T>. В C # есть несколько сокращений, например int? значит Nullable<int>, двойной? означает Nullable<double> и т. д.

Вы можете обернуть Nullable<T> только в ненулевые типы значений, что нормально, поскольку ссылки уже могут иметь значение null.

int? x = null;

Для целых чисел? Хотя вы можете проверить на нуль, иногда лучше позвонить x.HasValue().

В C # есть также оператор объединения nullable ?? когда вы хотите присвоить обнуляемый тип значения, не обнуляемый. Но если у вас нет оператора, вы можете вызвать GetValueOrDefault ().

int y = x ?? 2; // y becomes 2 if x is null.
int z = x.GetValueOrDefault(2); // same as y
2 голосов
/ 03 октября 2008

Это то, что вы ищете?

if IsNothing(foo) OrElse IsDbNull(foo) Then
    ' Do Something Because foo Is Either Nothing or DBNull.Value
End If

По правде говоря, я не уверен, почему вы захотите эту структуру. Единственный раз, когда я проверяю DBNULL.Value, это когда я использую значения, полученные из базы данных, и перед тем, как назначить указанное значение из класса пространства имен DATA другому классу [т.е. dim b as string = dataReader (0)].

Как правило, если вы беспокоитесь о том, что объект еще не был создан, или вам нужно, чтобы он был создан заново, тогда достаточно проверки IsNothing.

1 голос
/ 03 октября 2008

В .Net это только два типа null, о которых я знаю, null (ничего в VB) и DbNull. Если вы используете System.Nullable, вы можете использовать тот же синтаксис проверки нуля, что и для объекта. Если ваш обнуляемый объект упакован, CLR .Net 2.0 достаточно умен, чтобы найти правильный способ справиться с этим.

Единственный случай, когда я столкнулся с обоими типами, - это уровень данных приложения, где я мог бы напрямую обращаться к данным базы данных. Например, я столкнулся с DbNull в DataTable. Чтобы проверить оба этих нулевых типа в этой ситуации, вы можете написать метод расширения, например (извините, в C #):

static public bool IsNull(this object obj)
{
    return obj != null && obj != DbNull.Value;
}

...

if(dataTable[0]["MyColumn"].IsNull())
{
  //do something
}
0 голосов
/ 03 октября 2008

Пока вы разрабатываете с Option Strict On, (a) не должно быть проблемой. Компилятор будет кричать на тебя. Если вы беспокоитесь о проверке параметров, просто используйте

Public Sub MySub(ByVal param1 as MyObject, ByVal param2 as Integer)
    if param1 is nothing then
         Throw New ArgumentException("param1 cannot be null!")
    end if
    'param2 cannot be null
End Sub

Для (b) ваш уровень взаимодействия с базой данных должен справиться с этим. Если вы используете LINQ, есть способы справиться с этим. Если вы используете типизированные наборы данных, в строке, которая генерируется автоматически, есть свойство .IsMyVariableNull.

Для (c) вам не нужно беспокоиться о типах значений, но ссылочные типы можно проверить с помощью простого Is Nothing (или IsNot Nothing).

Для (d) вы можете применить ту же логику после чтения. Проверьте полученную переменную против Nothing.

По большей части, простая проверка «Ничего» поможет вам. Ваш слой взаимодействия с базой данных поможет вам справиться с более сложным случаем нулевых значений в ваших данных, но вы сами должны правильно их обработать.

0 голосов
/ 03 октября 2008

Переменные типа значения не могут содержать ноль, потому что нуль означает, что ноль означает, что ссылки никуда не указывают. Я не знаю, на VB.net, но на C # вы можете обернуть типы значений в обнуляемые, используя "?", Например:

int? a = null;
...