我对.NET中的空值和变量有点困惑。 (VB首选)
有没有办法检查任何给定变量的“nullness”,无论它是对象还是值类型?或者我的空检查是否必须始终预测它是在检查值类型(例如System.Integer)还是对象?
我想我正在寻找的是一个检查所有可能类型的无效的函数。也就是说,
的任何类型的变量 自从宣布以来,a)从未被分配过一个值
b)从数据对象(来自数据库)中分配了一个空值
c)被设置为等于另一个变量值为null
d)设置为从未设置或过期的ASP.NET会话/应用程序变量。
在.NET中处理空方案时是否有一般的最佳实践?
UPDATE:当我谈到一个值为“null”的值类型时,我真正的意思是一个值类型,它从未设置过,或者某个点设置为等于或从null转换宾语。
答案 0 :(得分:4)
值类型不能为空。它违反了价值类型的含义。您可以将值类型包装为Nullable(Of T),它为您提供了一组很好的方法,并检查Nothing是否正常工作。但是这个包装器确实有很多开销。也许你可以澄清你想要做什么?
为了完整性,Nullable包装器的VB语法是:
Dim i as Nullable(Of Integer) = Nothing '.NET 2.0/3.0'
Dim j as Integer? = Nothing '.NET 3.5'
编辑:值类型始终预先初始化为默认值,0表示数字,错误表示布尔值等。
答案 1 :(得分:2)
这就是你要追求的吗?
if IsNothing(foo) OrElse IsDbNull(foo) Then
' Do Something Because foo Is Either Nothing or DBNull.Value
End If
事实上,我不确定你为什么要这个结构。我唯一一次检查DBNULL.Value是在我使用来自数据库的值时,在我将所述值从DATA Namespace类分配给其他类之前[即dim b as string = dataReader(0)]。
通常,如果您担心某个对象尚未实例化,或者需要重新实例化,那么只需进行一次IsNothing检查即可。
答案 2 :(得分:2)
正常值类型(布尔值,整数,长整数,浮点数,双精度数,枚举数和结构数)不可为空。
所有值类型的默认值均为0.
除非已设置,否则CLR不允许您访问变量。您可能认为并非总是如此,但有时CLR会介入并为您初始化它们。在方法级别,您必须在使用它们之前显式初始化所有变量。
此外,正如其他人所指出的,因为.net 2.0有一个名为Nullable<T>
的新泛型类型。 C#中有一些编译器缩写,比如int?意味着Nullable<int>
,加倍?表示Nullable<double>
等。
你只能将Nullable<T>
包装在不可为空的值类型上,这很好,因为引用已经能够为null。
int? x = null;
对于int?,虽然你可以测试null,但有时候调用x.HasValue()
会更好。
在C#中还有nullable coalescing operator ??当您要将可空值分配给不可为空的值类型时。但是如果你没有运营商,你可以调用GetValueOrDefault()。
int y = x ?? 2; // y becomes 2 if x is null.
int z = x.GetValueOrDefault(2); // same as y
答案 3 :(得分:1)
在.Net中,我只知道两种类型的null,null(在VB中没有)和DbNull。如果您使用的是System.Nullable,则可以使用与对象相同的空检查语法。如果您的可空对象被装箱,那么.Net 2.0 CLR足够聪明,可以找到正确的方法来处理这个问题。
我遇到这两种类型的唯一情况是在应用程序的数据层中,我可能直接访问数据库数据。例如,我在DataTable中遇到了DbNull。要在此情境中检查这两种空类型,您可以编写一个类似的扩展方法(抱歉,在C#中):
static public bool IsNull(this object obj)
{
return obj != null && obj != DbNull.Value;
}
...
if(dataTable[0]["MyColumn"].IsNull())
{
//do something
}
答案 4 :(得分:0)
值类型变量不能包含null,因为null表示null,表示引用指向无处。我不知道在VB.net上,但在c#上,您可以使用“?”将值类型包装为nullables,如:
int? a = null;
答案 5 :(得分:0)
只要您使用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测试接收变量。
在大多数情况下,只需检查Is Nothing即可。您的数据库交互层将帮助您处理数据中空值的粘性情况,但您可以自行处理它们。