2012-09-18 16 views
2

在我的數據庫,V1現場爲空場。但是如果該值爲空,我將定義爲0(默認)。C#,可空小數

public decimal? v1 { 
    get { 
    return this._v1; 
    } 
    set { 
    this._v1 = value ?? 0M; 
    } 
} 

所以現在,v1不再是可爲空的變量。

,但我不能這樣做,

decimal v2 = v1; 

錯誤消息說,無法隱式轉換類型'小數?到'十進制'。

在這種情況下,我必須轉換爲十進制,這樣的嗎?

decimal v2 = Convert.ToDecimal(v1); 

這是非常討厭的工作。而且代碼也很髒。

任何人都知道更好的解決方案?請指教我。

+1

您的原始解決方案很髒,如果新解決方案很髒,有什麼關係。如果您爲其分配默認值,那麼擁有可爲空的字段的意義是什麼? –

+0

謝謝,我學到了很多:) –

回答

10

不,您不必轉換decimal?,您可以訪問Nullable類型的基礎值,例如,

decimal v2 = v1.Value; 

分配默認值設置爲Nullable類型不讓它不可爲空的,它只是意味着它有一個值。可爲空的類型有一個HasValue屬性,它可以幫助您確定這一點。

只是爲了記錄在案,我不會推薦值默認爲0它可能會更有意義讓它默認爲null考慮它可以確實爲空。如果你需要在你的應用程序的默認值,你可能會想例如使用GetValueOrDefault方法

decimal v2 = v1.GetValueOrDefault(0m); 
1

你分配到V1的值是decimal,但類型仍然是decimal?。這就是爲什麼你不能解決它。

嘗試

decimal v2 = v1.Value; 
1

可空類型有屬性ValueHasValue

的HasValue - 獲取一個指示當前可爲空對象是否具有值的值。

- 如果HasValue爲true,則包含該值(如果不爲空)。

decimal v2; 

if (v1.HasValue) // check for null 
{ 
    v2 = v1.Value; 
} 

退房MSDN - Nullable Types (C# Programming Guide)

4

轉換一個decimal?decimal,但必須是值的最簡單方法0null,你可以這樣做:

decimal? a = null; 
decimal b = a.GetValueOrDefault(0m); // will contain 0 when null, otherwise the value 

閱讀上GetValueOrDefault

您也可以調用GetValueOrDefault而不帶任何參數,這將產生default(T),在Decimal的情況下爲0,但我喜歡明確。

4

我很好奇爲什麼你會定義你的應用程序代碼變量爲空,但如果它爲空,然後將其設置爲0。如果將數據庫中的空值傳遞給應用程序變量,是否僅僅是爲了避免異常?如果您的應用程序並不絕對需要的可空小數變量,只是檢查了的DBNull爲你讀出來:

decimal myAppVal = rdr["DbColumn"] == DBNull.Value 
    ? default(decimal) 
    : (decimal) rdr["DbColumn"]; 

或明確設置的,而不是使用默認值(十進制)

0.0M在設計方面,如果你發現自己經常這樣做,那麼我會建議創建一個通用擴展方法來從數據庫中讀取值。通過這種方式,您可以確保避免無效轉換並處理異常,但更重要的是,在空值情況下會返回默認值。 ;)

喜歡的東西(我只是spitballing這裏):

public static T CastFromDbTo<T>(object readerObject) 
{ 
    T returnVal = default(T); 
    if (readerObject is T) 
    { 
     var myValue = (T) readerObject; 
     returnVal = readerObject != DbNull.Value && myValue != null 
       ? (T) readerObject 
       : default(T); 
    } 
    return returnVal; 
} 

然後,你可以抓住這樣你的價值:

var myAppValue = HelperClass.CastFromDbTo<decimal>(rdr["DbColumn"]); 

或實際提出延期:

public static T CastFromDbTo<T>(this object readerObject) 
{ 
    T returnVal = default(T); 
    if (readerObject is T) 
    { 
     var myValue = (T) readerObject; 
     returnVal = readerObject != DbNull.Value && myValue != null 
       ? (T) readerObject 
       : default(T); 
    } 
    return returnVal; 
} 

然後你可以這樣做:

var myAppVal = rdr["DbColumn"].CastFromDbTo<decimal>();