为什么以下编译?
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 ... }
但这不是
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 ... }
答案 0 :(得分:20)
接口工作的原因是任何对象可能实现IList<T>
(除非它已知是一个没有实现它的密封类型的实例,我猜) - 所以总是有一个可能的引用类型转换到接口。
在后一种情况下,编译器不愿意这样做,因为它并不真正知道T
是bool,尽管之前有if
语句,所以它不知道是什么转换为在MyClass<T>
和MyClass<bool>
之间尝试。遗憾的是,对泛型类型的有效转换非常有限。
你可以很容易地解决它:
return (MyClass<T>)(object) GetBoolValue(id);
这很难看,但它应该有用......至少在这种情况下它不会造成任何拳击。
答案 1 :(得分:0)
C#4.0允许在参数化接口和委托类型上声明协方差和逆变。
答案 2 :(得分:0)
如果替换
会发生什么 return (MyClass<T>)
与
return (MyClass<bool>)