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);