231

例外の説明にはパラドックスがあります: Nullable オブジェクトには値が必要です (?!)

これが問題です:

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

{
  DateTime? MyDataTime;
  int? otherdata;

}

とコンストラクタ

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

このコードを実行する

DateTimeExtended res = new DateTimeExtended(oldDTE);

InvalidOperationException次のメッセージとともに をスローします。

Null 許容オブジェクトには値が必要です。

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

このメッセージの意味と、何が間違っているのでしょうか?

oldDTEではないことに注意してくださいnullValuefromを削除しましたmyNewDT.MyDateTimeが、生成されたセッターが原因で同じ例外がスローされます。

4

8 に答える 8

237

this.MyDateTime = myNewDT.MyDateTime.Value;行を次のように変更する必要がありますthis.MyDateTime = myNewDT.MyDateTime;

受け取っていた例外は、 Nullableを返す必要があるため(状態の契約であるため)、の.Valueプロパティでスローされましたが、返すものがないため例外がスローされます。 DateTimeDateTime.ValueDateTime

一般に、null 許容型をやみくもに呼び出すのは、その変数に値が含まれている必要.Valueがあるという事前の知識がない限り(つまり、チェックによって) 、悪い考えです。.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);

.Valueonを追加するother.MyDateTimeと、例外が発生します。それを削除すると、例外が削除されます。私はあなたが間違った場所を見ていると思います。

于 2009-12-13T11:14:27.953 に答える
18

LINQ 拡張メソッド ( Select、 などWhere) を使用すると、ラムダ関数が SQL に変換され、C# コードと同じように動作しない可能性があります。たとえば、C# のショートサーキットは評価され、SQL のeager および に変換さ&&れます。これにより、ラムダで null をチェックしているときに問題が発生する可能性があります。||ANDOR

例:

MyEnum? type = null;
Entities.Table.Where(a => type == null || 
    a.type == (int)type).ToArray();  // Exception: Nullable object must have a value
于 2015-01-21T13:23:23.887 に答える
8

を落としてみてください.value

DateTimeExtended(DateTimeExtended myNewDT)
{
   this.MyDateTime = myNewDT.MyDateTime;
   this.otherdata = myNewDT.otherdata;
}
于 2009-12-13T11:12:30.773 に答える
2

.Valueパーツなしでメンバーを直接割り当てます。

DateTimeExtended(DateTimeExtended myNewDT)
{
   this.MyDateTime = myNewDT.MyDateTime;
   this.otherdata = myNewDT.otherdata;
}
于 2009-12-13T11:13:25.970 に答える
2

この場合、oldDTE は null であるため、oldDTE.Value にアクセスしようとすると、値がないため InvalidOperationException がスローされます。あなたの例では、次のように簡単に実行できます。

this.MyDateTime = newDT.MyDateTime;
于 2009-12-13T11:13:32.487 に答える
0

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

sName = myObj.Name;

これによりエラーが発生します。まず、オブジェクトがnullでないかどうかを確認する必要があります

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

これは機能します。

于 2012-09-28T13:19:36.597 に答える
0

oldDTE.MyDateTime が null だったように見えるため、コンストラクターは値を取得しようとしましたが、これがスローされました。

于 2009-12-13T11:14:43.417 に答える