2009-12-13 12 views
144

を持っている必要があります例外の説明におけるパラドックスがあります:(?!) のNullableオブジェクトが値を持っている必要がありますNULL可能オブジェクトが値

を、これは問題です:

私が持っているDateTimeExtendedクラス、 を持っています

{ 
    DateTime? MyDataTime; 
    int? otherdata; 

} 

とコンストラクタ

DateTimeExtended(DateTimeExtended myNewDT) 
{ 
    this.MyDateTime = myNewDT.MyDateTime.Value; 
    this.otherdata = myNewDT.otherdata; 
} 
このコード

DateTimeExtended res = new DateTimeExtended(oldDTE); 

を実行210

メッセージとInvalidOperationExceptionをスロー:

NULL可能オブジェクトが値を持たなければなりません。

myNewDT.MyDateTime.Value - は有効で、通常のDateTimeオブジェクトを含んでいます。

このメッセージの意味は何ですか、何が間違っていますか?

oldDTEnullではありません。私はValuemyNewDT.MyDateTimeから削除しましたが、生成されたセッターのために同じ例外がスローされます。

+0

他のコンストラクタは何ですか? –

+0

奇妙な。私はそこに.Valueの例外を再現し、そこには.Valueがなければ例外はありません。更新されたコードを実行していますか? – Yuliy

+0

コンストラクタは、自身のインスタンスを取ります。最初のインスタンスをどうやって作りましたか? –

答えて

147

あなただけthis.MyDateTime = myNewDT.MyDateTime;

あなたが受けていた例外はそれとして、のNullableDateTime.Valueプロパティでスローされたためにラインthis.MyDateTime = myNewDT.MyDateTime.Value;を変更する必要がありますDateTimeを返す必要があります(これは.Valueの契約と同じです)。返すものがDateTimeではないため、そうすることはできません。したがって、例外がスローされます。一般的に

、あなたには、いくつかの予備知識を持っていない限り、それは、盲目的にNULL可能タイプに.Valueを呼び出すことは悪い考えである変数MUST(すなわち.HasValueチェックを)値が含まれていること。

EDIT

はここで例外をスローしませんDateTimeExtendedためのコードです:

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

    public DateTimeExtended() { } 

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

私はこのようにそれをテストした:other.MyDateTime.Valueを追加

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

が原因例外。それを削除すると、例外が取り除かれます。私はあなたが間違った場所を探していると思う。

+0

.valueについては正しいですが、何か例外が発生します。 .valueを削除しました。コンストラクタのコード順を変更しました。まずint値をコピーしますが、同じ例外がスローされます。 – Dani

+0

私は質問にコメントしました - 問題が見つかりました、それはプロパティの生成されたセッターにあった。 – Dani

+0

はい、その解決された私の問題は、私はヌル可能なヌル可能なオブジェクトを変更し、datetimeobject.value.datetime.tostring()ではなく、直接文字列にdatetimeを変換します。 – adnan

4

.VALUE

+0

が役に立たなかったためです。最初に2行目を実行すると同じ例外がスローされます。 – Dani

1

が直接.Value一部せずにメンバーを割り当てるドロップしてみてください。あなたがいるのでスローされる例外InvalidOperationException oldDTE.Valueアクセスしようとしたそう際、

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

oldDTEがnullこの場合、価値はありません。あなたの例では、単に行うことができます。

this.MyDateTime = newDT.MyDateTime; 
+0

oldDTEはnullではありませんが、値を削除しています...それでも例外はスローされています.... – Dani

0

oldDTE.MyDateTimeがnullのように見えるので、コンストラクタは値を取り込もうとしました。

0

null値のオブジェクトの値にアクセスしようとすると、このメッセージが表示されます。

sName = myObj.Name; 

これによりエラーが発生します。まず、オブジェクトがヌルでないかどうかチェックしてください。

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

これは機能します。

+0

答えを出す前に、まず質問の他の回答を読んでみてください。特にあなたの*答えに記載されている内容を正確に述べた受け入れられた答え。それはコードを使用して表示されませんが、それはそれを綴ります。また、 's.name = myObj.Name;ではなく' this.MyDateTime = myNewDT.MyDateTime.Value; 'のような質問に関連するサンプルコードを作成してみてください – newfurniturey

2

LINQ拡張メソッド(たとえばSelectWhere)を使用する場合、ラムダ関数はC#コードと同じように動作しないSQLに変換される可能性があります。例えば、||&&と評価されたC#の短絡は、SQLの熱心なANDORに変換されます。これはラムダでヌルをチェックしているときに問題を引き起こす可能性があります。

例:

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

私はこの答えがOPの特殊なケースとは無関係であることを認識していますしかし、それは彼が得ている例外に関連しています。また、このページはその例外のためのGoogleの最初のヒットであり、関連性があります。 –

関連する問題