C# 仿制药与铸造
为什么要编译下面的代码C# 仿制药与铸造,c#,generics,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 x
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 IList反序列化(字符串xml)
{
if(typeof(T)=typeof(bool))
返回(IList)反序列化工具(xml);
返回null;
}
私有静态IList反序列化工具(字符串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 ... }
public MyClass GetFromDb(字符串id)
{
if(typeof(T)=typeof(bool))
return(MyClass)GetBoolValue(id);C#4.0允许在参数化的接口和委托类型上声明协方差和逆变换。如果替换
return(MyClass)
与
返回(MyClass)
接口工作的原因是任何对象都可能实现IList
(除非已知它是一个密封类型的实例,但它没有实现它),所以总是有一个可能的引用类型转换到接口
在后一种情况下,编译器不愿意这样做,因为它不知道t
是bool,尽管前面有if
语句,所以它不知道在MyClass
和MyClass
之间尝试什么转换。不幸的是,到泛型类型的有效转换非常有限
您可以相当轻松地修复它:
return (MyClass<T>)(object) GetBoolValue(id);
return(MyClass)(object)GetBoolValue(id);
这很难看,但它应该可以工作…至少在这种情况下,它不会导致任何装箱。编译错误是什么…错误说明了什么?无法将类型为“MyClass”的表达式强制转换为类型为“MyClass”,那么它将无法从MyClass
转换为返回类型所需的MyClass
。这不是尝试使用Genereric变量,而且无论如何,泛型变量不适用于值类型参数。
return (MyClass<T>)(object) GetBoolValue(id);