views:

2231

answers:

5

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;
   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 regulare DateTime object.

What is the meaning of this message and what am I doing wrong ?

* EDIT: oldDTE is NOT NULL I've removed the Value from myNewDT.MyDateTime but same exception thrown.**

Thanks.

+2  A: 

Try dropping the .value

Paul Creasey
doesn't help. it throws the same exception if I run the 2nd line first.
Dani
+1  A: 

Assign the members directly without the .Value part:

DateTimeExtended(DateTimeExtended myNewDT)
{
   this.MyDateTime = myNewDT.MyDateTime;
   this.otherdata = myNewDT.otherdata;
}
Cecil Has a Name
+1  A: 

In this case oldDTE is null, so when you try to access oldDTE.Value the InvalidOperationException is thrown since there is no value. In your example you can simply do:

this.MyDateTime = newDT.MyDateTime;
Lee
The oldDTE is not null, but I removed the value anyhow... it is still throwing that exception....
Dani
+4  A: 

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.

Yuliy
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.
Dani
I've commented on the question - found the problem, it was in a generated setter for the properties.
Dani
+1  A: 

Looks like oldDTE.MyDateTime was null, so constructor tried to take it's Value - which threw.

Pavel Radzivilovsky