2012-05-17 60 views
5

今天我和一位同事進行了一次有趣的討論。我們在C#中討論了兩段代碼。將null填充到某個東西?

代碼片段:

if(!reader.IsDBNull(2)) 
{ 
    long? variable1 = reader.GetInt64(2) 
} 

代碼片段2:

long variable1 = reader.IsDBNull(2) ? (long?) null : reader.GetInt64(2) 

的問題是:這是一個很好的做法,投空成一個可空長?或者你寧願使用傳統的if語句來避免將null設爲可空。

+1

那麼演員陣營是你使用的條件運算符,它需要分支的返回類型是類似的,snippet2是編譯器錯誤,你需要它是'長? variable1' – V4Vendetta

+0

正如V4Vendetta所說,在你的第二個片段中,你的lh和rh類型是不同的。 –

+0

在snippet1中,'variable1'只存在於'if'的範圍內。 – comecme

回答

15

表達(type?)nulldefault(type?)new Nullable<type>()最終被編譯成相同的操作碼:

 long? x = (long?)null; 
     long? y = default(long?); 
     long? z = new Nullable<long>(); 

變成:

IL_0001: ldloca.s x 
    IL_0003: initobj valuetype [mscorlib]System.Nullable`1<int64> 
    IL_0009: ldloca.s y 
    IL_000b: initobj valuetype [mscorlib]System.Nullable`1<int64> 
    IL_0011: ldloca.s z 
    IL_0013: initobj valuetype [mscorlib]System.Nullable`1<int64> 

換句話說,如果您正在使用可空類型的工作,您可以自由使用哪個版本,你最喜歡的。但請注意,您應該儘量避免使用可爲空的類型進行運算。如果您想從條件表達式返回一個可爲空的值,那麼如果其中一個可能爲空,則兩個可能的結果都必須爲空。在這種情況下,任何其他方式都可能導致異常。

+0

爲了完整:表達式'null as type?'也被編譯成同樣的IL代碼,事實上,如果周圍的表達式提供了可以爲空的類型的上下文,例如'condition?null:value as type?'。該表達式中的'null'也編譯爲'new Nullable'IL代碼。 – Wormbo

1

我寧願不投null值(它看起來很奇怪我):

long? variable1 = reader.IsDBNull(2) ? null : (long?)reader.GetInt64(2); 

另一種選擇:

long? variable1 = reader.IsDBNull(2) ? default(long?) : reader.GetInt64(2); 
long? variable1 = reader.IsDBNull(2) ? (long?)null : reader.GetInt64(2); 
long? variable1 = reader.IsDBNull(2) ? new Nullable<long>() : reader.GetInt64(2); 
long? variable1 = reader.IsDBNull(2) ? new long?() : reader.GetInt64(2); 
long? variable1 = reader.IsDBNull(2) ? null : new long?(reader.GetInt64(2)); 

它的味道只是此事。我認爲第一選擇比其他選項更具可讀性。

UPDATE:還考慮寫一些擴展方法,使你的代碼更加清晰:

public static class DataReaderExtensions 
{ 
    public static long? GetNullableInt64(this IDataReader reader, int index) 
    { 
     if (reader.IsDBNull(index)) 
      return null; 

     return reader.GetInt64(index); 
    } 
} 

在這種情況下,您不使用三元操作符(不鑄件可空),並讀取值從讀者看起來更漂亮:

long? variable1 = reader.GetNullableInt64(2); 
+0

@lazyberezovsky因爲你**不能將null轉換爲long?** – V4Vendetta

+0

@ V4Vendetta我在第一條評論之前修復了這個錯字 –

+0

@lazyberezovsky你還有它......「? null:(long?)reader.GetInt64(2)':( – V4Vendetta

0

片段2是我的價值的情況下,如在null情況下,你會得到0,這是long

一個完全有效的值3210
3

代替

(long?) null 

使用

default(long?) 

我將重構上面的代碼等

long? variable1 = reader.IsDBNull(2) ? default(long?) : reader.GetInt64(2) 
+0

爲什麼你在第二個括號內使用'long?'? –

+0

typo in剪切複製粘貼,thansk指出 – Tilak

相關問題