簡體   English   中英

.NET DBNull vs所有變量類型都沒有?

[英].NET DBNull vs Nothing across all variable types?

我對.NET中的空值和變量有點困惑。 (VB首選)

有沒有辦法檢查任何給定變量的“nullness”,無論它是對象還是值類型? 或者我的空檢查是否必須始終預測它是在檢查值類型(例如System.Integer)還是對象?

我想我正在尋找的是一個檢查所有可能類型的無效的函數。 也就是說,任何類型的變量

a)自從宣布以來從未被賦予價值

b)從數據對象(來自數據庫)中分配了一個空值

c)被設置為等於另一個為null的變量值

d)設置為從未設置或過期的ASP.NET會話/應用程序變量。

在.NET中處理空方案時是否有一般的最佳實踐?

更新:當我談到一個值為“null”的值類型時,我真正的意思是一個值類型,它從未設置過,或者在某個點設置為等於或從空對象轉換。

值類型不能為空。 它違反了價值類型的含義。 您可以將值類型包裝為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表示數字,錯誤表示布爾值等。

這就是你要追求的嗎?

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檢查就足夠了。

正常值類型(布爾值,整數,長整數,浮點數,雙精度數,枚舉數和結構數)不可為空。

所有值類型的默認值均為0。

除非已設置,否則CLR不允許您訪問變量。 您可能認為並非總是如此,但有時CLR會介入並為您初始化它們。 在方法級別,您必須在使用之前顯式初始化所有變量。

此外,正如其他人所指出的,因為.net 2.0有一個名為Nullable<T>的新泛型類型。 C#中有一些編譯器縮寫,比如int? 意味着Nullable<int> ,double? 可以為Nullable<double>

你只能將Nullable<T>包裝在不可為空的值類型上,這很好,因為引用已經能夠為null。

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

在.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
}

值類型變量不能包含null,這是因為null表示null,表示引用指向任何地方。 我不知道在VB.net上,但在c#上,您可以使用“?”將值類型包裝為nullables,如:

int? a = null;

只要您使用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會讓您滿意。 您的數據庫交互層將幫助您處理數據中空值的粘性情況,但您可以自行適當地處理它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM