Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics and Casting

Tags:

c#

generics

Why does the following compile?

public IList<T> Deserialize<T>(string xml)
{              
    if (typeof(T) == typeof(bool))
        return (IList<T>)DeserializeBools(xml);

    return null;
}

private static IList<bool> DeserializeBool(string xml) { ... do stuff ... }

But this doesn't

public MyClass<T> GetFromDb<T>(string id)
{
    if (typeof(T) == typeof(bool))
        return (MyClass<T>)GetBoolValue(id);  <-- compiler error here

    return null;
}

private static MyClass<bool> GetBoolValue(string id) { ... do stuff ... }
like image 745
Magpie Avatar asked Oct 29 '10 10:10

Magpie


1 Answers

The reason interfaces work is that any object might implement IList<T> (unless it's known to be an instance of a sealed type which doesn't implement it, I guess) - so there's always a possible reference type conversion to the interface.

In the latter case, the compiler isn't willing to do that because it doesn't really know that T is bool, despite the previous if statement, so it doesn't know what conversion to try between MyClass<T> and MyClass<bool>. The valid conversions to generic types are pretty limited, unfortunately.

You can fix it fairly easily:

return (MyClass<T>)(object) GetBoolValue(id);

It's ugly, but it should work... and at least in this case it won't be causing any boxing.

like image 150
Jon Skeet Avatar answered Sep 30 '22 19:09

Jon Skeet