泛型和铸造

Mag*_*pie 11 c# generics

为什么以下编译?

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 ... }
Run Code Online (Sandbox Code Playgroud)

但事实并非如此

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 ... }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 20

接口工作的原因是任何对象都可能实现IList<T>(除非它已知是一个没有实现它的密封类型的实例,我猜) - 所以总是有一个可能的引用类型转换到接口.

在后一种情况下,编译器也不愿意这样做,因为它并没有真正知道T是布尔,尽管前面的if语句,所以它不知道之间什么尝试转换MyClass<T>MyClass<bool>.遗憾的是,对泛型类型的有效转换非常有限.

你可以很容易地解决它:

return (MyClass<T>)(object) GetBoolValue(id);
Run Code Online (Sandbox Code Playgroud)

这很难看,但它应该有效......至少在这种情况下它不会造成任何拳击.