There is paradox in the exception description: Nullable object must have a value (?!)
This is the problem:
I have a DateTimeExtended
class,
that has
{
DateTime? MyDataTime;
int? otherdata;
}
and a constructor
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime.Value;
this.otherdata = myNewDT.otherdata;
}
running this code
DateTimeExtended res = new DateTimeExtended(oldDTE);
throws an InvalidOperationException
with the message:
Nullable object must have a value.
myNewDT.MyDateTime.Value
- is valid and contain a regular DateTime
object.
What is the meaning of this message and what am I doing wrong?
Note that oldDTE
is not null
. I've removed the Value
from myNewDT.MyDateTime
but the same exception is thrown due to a generated setter.
You should change the line this.MyDateTime = myNewDT.MyDateTime.Value;
to just this.MyDateTime = myNewDT.MyDateTime;
The exception you were receiving was thrown in the .Value
property of the Nullable DateTime
, as it is required to return a DateTime
(since that's what the contract for .Value
states), but it can't do so because there's no DateTime
to return, so it throws an exception.
In general, it is a bad idea to blindly call .Value
on a nullable type, unless you have some prior knowledge that that variable MUST contain a value (i.e. through a .HasValue
check).
EDIT
Here's the code for DateTimeExtended
that does not throw an exception:
class DateTimeExtended
{
public DateTime? MyDateTime;
public int? otherdata;
public DateTimeExtended() { }
public DateTimeExtended(DateTimeExtended other)
{
this.MyDateTime = other.MyDateTime;
this.otherdata = other.otherdata;
}
}
I tested it like this:
DateTimeExtended dt1 = new DateTimeExtended();
DateTimeExtended dt2 = new DateTimeExtended(dt1);
Adding the .Value
on other.MyDateTime
causes an exception. Removing it gets rid of the exception. I think you're looking in the wrong place.
You are right about the .value, yet something else causes the exception. I've removed the .value, and i've changed the code order of the constructor- copying the int value first, but same exception is thrown.
I've commented on the question - found the problem, it was in a generated setter for the properties.
yes, its resolved my problem, i just change null able object to non null able, and convert datetime to string directly, not by datetimeobject.value.datetime.tostring()
Great answer. Getting an exception calling
.Value
on a null object makes sense (I guess), but the exception message is really misleading if you happen to be dealing with two Nullable objects. Something like 'The .Value property requires the object to be non-null' would make a whole lot more sense.