例外の説明にはパラドックスがあります。Nullableオブジェクトには値(?!)が必要です
これが問題です:
DateTimeExtended
クラスがあります。
{
DateTime? MyDataTime;
int? otherdata;
}
およびコンストラクター
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime.Value;
this.otherdata = myNewDT.otherdata;
}
このコードを実行する
DateTimeExtended res = new DateTimeExtended(oldDTE);
メッセージとともにInvalidOperationException
をスローします。
Nullableオブジェクトには値が必要です。
myNewDT.MyDateTime.Value
-有効であり、通常のDateTime
オブジェクトが含まれています。
このメッセージの意味は何ですか?また、私は何を間違っていますか?
oldDTE
はnull
ではないことに注意してください。 myNewDT.MyDateTime
からValue
を削除しましたが、セッターが生成されたために同じ例外がスローされます。
行this.MyDateTime = myNewDT.MyDateTime.Value;
を単にthis.MyDateTime = myNewDT.MyDateTime;
に変更する必要があります
あなたが受け取っていた例外は.Value
NullableDateTime
のプロパティでスローされました。DateTime
を返す必要があるためです.Value
のコントラクト)ですが、返されるDateTime
がないため、返せないため、例外がスローされます。
一般に、その変数MUSTに値が含まれているという事前知識がない限り(つまり.Value
を介して)、null許容型で盲目的に.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);
.Value
にother.MyDateTime
を追加すると、例外が発生します。それを削除すると、例外は取り除かれます。間違った場所を見ていると思います。
LINQ拡張メソッド(Select
、Where
など)を使用する場合、ラムダ関数はSQLに変換され、C#コードとまったく同じように動作しない場合があります。たとえば、C#の短絡評価||
および&&
は、SQLの熱心なAND
およびOR
に変換されます。これは、ラムダでnullをチェックしているときに問題を引き起こす可能性があります。
例:
MyEnum? type = null;
Entities.Table.Where(a => type == null ||
a.type == (int)type).ToArray(); // Exception: Nullable object must have a value
.valueをドロップしてみてください
この場合、oldDTEはnullであるため、oldDTE.Valueにアクセスしようとすると、値がないためInvalidOperationExceptionがスローされます。あなたの例では、単に次のことができます:
this.MyDateTime = newDT.MyDateTime;
.Value
部分なしでメンバーを直接割り当てます。
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime;
this.otherdata = myNewDT.otherdata;
}
OldDTE.MyDateTimeがnullのように見えるため、コンストラクタはValueを取得しようとしましたが、これがスローされました。
Null値のオブジェクトの値にアクセスしようとしたときにこのメッセージが表示されました。
sName = myObj.Name;
これによりエラーが発生します。最初に、オブジェクトがnullでないかどうかを確認する必要があります
if(myObj != null)
sName = myObj.Name;
これは動作します。