Nullable DateTime extension throws 'does not contain a definition' exception

14,793

That's not an exception that's thrown, that's a compiler error. The former happens at runtime, the latter at compile time. It's an important difference.

You get this error because the compiler can't find an extension method accepting a DateTime, only one with a DateTime?. Those are entirely different types. Nullable<T> has no inheritance relation whatsoever to T, so you can't make an overload for Nullable<T> accept a T, nor vice versa.

You can combine the methods by letting one call the other:

public static class Extensions
{
    public static DateTime ToCleanDateTime(this DateTime dt)
    {
      return new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0, 0);      
    }

    public static DateTime? ToCleanDateTime(this DateTime? dt)
    {
        if (dt.HasValue)
        {
            return dt.Value.ToCleanDateTime();
        }
        return dt;
    }
}

Or you can just use DateTime.Date, which returns the same as your extension method and preserves the Kind, as opposed to the above code with which Kind will be Unspecified regardless the input's Kind.

Share:
14,793

Related videos on Youtube

CrnaStena
Author by

CrnaStena

Software developer at heart, since I was little (those that know me would argue I was never little). Video gamer at heart as well, so putting in time to collect badges and reputation is like second nature by now. Time to quest!

Updated on July 29, 2022

Comments

  • CrnaStena
    CrnaStena almost 2 years

    In the code below:

    void Main()
    {
        DateTime cleanDate = DateTime.Now.ToCleanDateTime();    
        DateTime? nullableCleanDate = DateTime.Now;
        nullableCleanDate = nullableCleanDate.ToCleanDateTime();
    
        cleanDate.Dump();
        nullableCleanDate.Dump();
    }
    
    public static class Extensions
    {
        //public static DateTime ToCleanDateTime(this DateTime dt)
        //{
        //  dt = new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0, 0);
        //  return dt;
        //}
    
        public static DateTime? ToCleanDateTime(this DateTime? dt)
        {
            if (dt.HasValue)
                dt = new DateTime(dt.Value.Year, dt.Value.Month, dt.Value.Day, 0, 0, 0, 0);
            return dt;
        }
    }
    

    This line DateTime cleanDate = DateTime.Now.ToCleanDateTime(); throws following exception.

    'System.DateTime' does not contain a definition for 'ToCleanDateTime' and the best extension method overload 'Extensions.ToCleanDateTime(System.DateTime?)' has some invalid arguments

    If I comment in extension method for DateTime public static DateTime ToCleanDateTime(this DateTime dt) error is not thrown.

    Could anyone enlighten me with:

    1. Why is this error thrown (aside from the obvious)?
    2. Is there a way to combine these two extensions into single method?

    I somehow expected public static DateTime? ToCleanDateTime(this DateTime? dt) to handle both DateTime and DateTime?.

    • Ron Beyer
      Ron Beyer about 9 years
      As your answer says, DateTime != DateTime? because DateTime? is turned into Nullable<DateTime> by the compiler. Its a completely different type.
  • HardcoreGameDev
    HardcoreGameDev almost 3 years
    This does not answer the question.