2009-12-13 47 views
144

有矛盾的異常說明: 可空對象必須有一個值可空對象必須有一個價值

這是問題(?!):

我有一個DateTimeExtended類, 有

{ 
    DateTime? MyDataTime; 
    int? otherdata; 

} 

和構造

DateTimeExtended(DateTimeExtended myNewDT) 
{ 
    this.MyDateTime = myNewDT.MyDateTime.Value; 
    this.otherdata = myNewDT.otherdata; 
} 

運行此代碼

DateTimeExtended res = new DateTimeExtended(oldDTE); 

拋出並顯示消息InvalidOperationException

可爲空的對象必須有一個值。

myNewDT.MyDateTime.Value - 有效且包含常規DateTime對象。

此消息的含義是什麼,我做錯了什麼?請注意0​​不是null。我已經從myNewDT.MyDateTime中刪除了Value,但由於生成的setter會導致相同的異常。

+0

什麼其他的構造? –

+0

奇怪。我用那裏的.Value重現異常,沒有.Value的情況下不會出現異常。你確定你正在運行更新的代碼嗎? – Yuliy

+0

構造函數接受它自己的一個實例。你如何創建第一個實例? –

回答

147

你應該改變行this.MyDateTime = myNewDT.MyDateTime.Value;只是this.MyDateTime = myNewDT.MyDateTime;

你收到異常被拋出的可空DateTime.Value財產,因爲它需要返回DateTime(因爲這是.Value狀態的合同),但它不能這樣做,因爲沒有DateTime要返回,所以它會引發異常。

在一般情況下,這是一個壞主意,一味呼籲.Value上可空類型,除非你有一些事先知道該變量MUST包含的值(即通過.HasValue檢查)。

編輯

下面是DateTimeExtended代碼不拋出異常:

class DateTimeExtended 
{ 
    public DateTime? MyDateTime; 
    public int? otherdata; 

    public DateTimeExtended() { } 

    public DateTimeExtended(DateTimeExtended other) 
    { 
     this.MyDateTime = other.MyDateTime; 
     this.otherdata = other.otherdata; 
    } 
} 

我測試它像這樣:

DateTimeExtended dt1 = new DateTimeExtended(); 
DateTimeExtended dt2 = new DateTimeExtended(dt1); 

添加上other.MyDateTime.Value導致例外。刪除它可以排除異常。我認爲你看錯了地方。

+0

您對.value是正確的,但其他情況會導致異常。 我已經刪除了.value,並且我已經更改了構造函數的代碼順序 - 首先複製了int值,但引發了相同的異常。 – Dani

+0

我已經評論了這個問題 - 發現問題,它是在一個生成的屬性setter中。 – Dani

+0

是的,它解決了我的問題,我只是將null能夠對象更改爲非null能夠,並將datetime直接轉換爲字符串,而不是通過datetimeobject.value.datetime.tostring() – adnan

4

嘗試丟棄.value的

+0

沒有幫助。它會引發同樣的異常,如果我先運行第二行。 – Dani

1

指定成員的情況下直接將.Value部分:

DateTimeExtended(DateTimeExtended myNewDT) 
{ 
    this.MyDateTime = myNewDT.MyDateTime; 
    this.otherdata = myNewDT.otherdata; 
} 
1

在這種情況下oldDTE爲空,所以當您嘗試訪問oldDTE.Value的出現InvalidOperationException,因爲被拋出沒有價值。在您的例子,你可以簡單地做:

this.MyDateTime = newDT.MyDateTime; 
+0

oldDTE不爲null,但我無論如何刪除了該值......它仍在拋出該異常...... – Dani

0

看起來像oldDTE.MyDateTime是空的,所以構造函數試圖把它的價值 - 投擲。

0

嘗試訪問空值對象的值時,我收到了此消息。

sName = myObj.Name; 

這會產生錯誤。首先你應該檢查對象是否爲空

if(myObj != null) 
    sName = myObj.Name; 

這是有效的。

+0

在回答之前,請先嚐試通讀其他問題的答案 - 尤其是接受的答案,確切地說明了您在*答案中放置的內容。儘管它沒有使用代碼來展示它,但它將它拼出來。此外,嘗試使您的示例代碼與問題的相關 - 例如'this.MyDateTime = myNewDT.MyDateTime.Value;',而不是'sName = myObj.Name;' – newfurniturey

2

當使用LINQ擴展方法(例如SelectWhere)時,lambda函數可能會轉換爲SQL,這可能與您的C#代碼行爲不同。例如,C#的短路評估||&&被轉換爲SQL的渴望ANDOR。當您在您的lambda中檢查null時,這可能會導致問題。

例子:

MyEnum? type = null; 
Entities.Table.Where(a => type == null || 
    a.type == (int)type).ToArray(); // Exception: Nullable object must have a value 
+0

我意識到這個答案與OP的特定案例無關,但它與他得到的異常有關。此外,此頁面是Google在該例外情況下的第一次訪問,因此具有相關性。 –

相關問題