6

我对 .NET 中的空值和变量有点困惑。(首选VB)

有没有办法检查任何给定变量的“nullness”,无论它是对象还是值类型?还是我的空检查必须始终预测它是检查值类型(例如 System.Integer)还是对象?

我想我正在寻找的是一个检查所有可能的空值的函数。也就是说,任何类型的变量

a) 自声明以来从未被赋值

b)从数据对象(来自数据库)中分配了一个空值

c) 被设置为等于另一个为空的变量值

d) 设置为从未设置或过期的 ASP.NET 会话/应用程序变量。

在 .NET 中处理空场景时是否有一般的最佳实践?

更新:当我谈论一个值类型为“null”时,我真正的意思是一个值类型,它要么从未设置,要么在某些时候设置为等于或从空对象强制转换。

4

6 回答 6

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,布尔值为 false 等。

于 2008-10-02T21:34:05.967 回答
2

这就是你所追求的吗?

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 检查就足够了。

于 2008-10-02T21:40:02.677 回答
2

普通值类型(布尔值、整数、长整数、浮点数、双精度、枚举和结构)不能为空。

所有值类型的默认值为 0。

CLR 不会让您访问变量,除非它们已被设置。您可能认为情况并非总是如此,但有时 CLR 会介入并为您初始化它们。在方法级别,您必须在使用所有变量之前显式初始化它们。

此外,正如其他人指出的那样,由于 .net 2.0 有一个新的泛型类型,称为Nullable<T>. C# 中有一些编译器简写,比如 int? 意思是Nullable<int>,双?手段Nullable<double>

您只能包装Nullable<T>不可为空的值类型,这很好,因为引用已经能够为空。

int? x = null;

对于 int?,虽然您可以针对 null 进行测试,但有时调用x.HasValue().

在 C# 中还有可以为空的合并运算符?? 当您想将可为空的值分配给不可为空的值类型时。但是如果你没有操作符,你可以调用GetValueOrDefault()。

int y = x ?? 2; // y becomes 2 if x is null.
int z = x.GetValueOrDefault(2); // same as y
于 2008-10-03T00:12:38.580 回答
1

在 .Net 中,我知道只有两种类型的 null,null(在 VB 中没有)和 DbNull。如果您使用 System.Nullable,则可以使用与对象相同的 null 检查语法。如果您的可空对象被装箱,.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
}
于 2008-10-02T21:47:24.017 回答
0

值类型变量不能包含 null,那是因为 null 是什么意思,null 表示引用不指向任何地方。我在 VB.net 上不知道,但在 c# 上,您可以使用“?”将值类型包装为可空值,例如:

int? a = null;
于 2008-10-02T21:35:20.177 回答
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 进行简单的检查就可以了。您的数据库交互层将帮助您处理数据中更棘手的空值情况,但如何正确处理它们取决于您。

于 2008-10-02T21:49:15.367 回答