Cannot change type to nullable in generic method

.net-3.5, c#, casting, generics, nullable

Solution

The thrown exception says that it cannot convert from `DateTime` to `Nullable<DateTime>`. Since, the method creates and returns a nullable type, how come the casting fails?

Good question. This fails because there is no such thing as a boxed nullable. When you convert a `DateTime?` to `object`, you either get a null reference, if the `DateTime?` was null, or you get the boxed value, a `DateTime`. You never get a boxed nullable struct; there is no such thing.

Therefore you end up with either null, or a valid DateTime in that box. You then tell Convert to convert that to a nullable DateTime, and Convert does not know how to do that.

My advice is that you abandon this line of attack entirely; this code is borderline abusive of generics. Any time you make a switch on the specific type of a generic, your code is no longer generic and you are probably doing it wrong. If you want to do a "try"-style method for datetimes then just write that:

DateTime? TryReadDateTime(object data)
{
    ... return null if the object cannot be read as a datetime ...
}

Write such a method for every type that you intend to read. The user would much rather write:

DateTime? d = TryReadDateTime(data);
if (d != null) ...

Than

DateTime d;
bool b = TryRead<DateTime>(data, out d);
if (b) ...

Problem

I am creating a generic converter Here is a sample code of the generic converter ``` bool TryReaderParse<TType>(object data, out TType value) { value = default(TType); Type returnType = typeof(TType); object tmpValue = null; if (returnType == typeof(DateTime)) { tmpValue = StringToDatetime(data.ToString()); } else if (returnType == typeof(DateTime?)) // THIS IF FIRES { tmpValue = StringToNullableDatetime(data.ToString()); } value = (TType)Convert.ChangeType(tmpValue, returnType); // THROWS } public DateTime? StringToNullableDatetime(string date) { DateTime? datetime = null; if (!string.IsNullOrEmpty(date)) { datetime = DateTime.Parse(date, new CultureInfo(Resources.CurrentCulture)); } return datetime; } ``` And this is how I use it: ``` void foo() { DateTime? date = null; TryReaderParse<DateTime?>("25/12/2012", out date); } ``` The thrown exception says that it cannot convert from `DateTime` to `Nullable<DateTime>`. Since, the method creates and returns a nullable type, how come the casting fails? At the end, I want to have a nullable DateTime, in this particular example. edit The problem is that `StringToNullableDatetime` method returns a `Datetime?` and the casting says that cannot convert from `Datetime` Since the `StringToNullableDatetime` method returns a nullable datetime, how is it possible that the `Convert.ChangeType` cannot see that the passed argument is nullable? Ps. I've read answers like this one that do the opposite (casting from nullable).

Original source

Related problems