Search code examples
c#nullableinvalidoperationexception

nullable object must have a value


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.


Solution

  • 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.