简体   繁体   English

泛型和强制转换

[英]Generics and Casting

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 ... }

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. 接口起作用的原因是任何对象都可以实现IList<T> (除非我猜它是密封类型的实例,否则我不会实现)-因此,始终有可能将引用类型转换为接口。

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> . 在后一种情况下,编译器不愿意这样做,因为尽管有前面的if语句,但它并不真正知道T是布尔值,因此它不知道在MyClass<T>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. 它很丑陋,但是应该可以工作……至少在这种情况下,它不会引起任何拳击。

C#4.0允许在参数化接口和委托类型上声明协方差和协方差。

What happens if you replace 如果您更换会怎样?

return (MyClass<T>)

with

return (MyClass<bool>)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM