In 泛型常见问题解答:最佳实践 says :
编译器将允许您将泛型类型参数显式转换为任何接口,但不能转换为类:
interface ISomeInterface
{...}
class SomeClass
{...}
class MyClass<T>
{
void SomeMethod(T t)
{
ISomeInterface obj1 = (ISomeInterface)t;//Compiles
SomeClass obj2 = (SomeClass)t; //Does not compile
}
}
我认为类和接口的限制都是合理的,除非类/接口未指定为约束类型。
那么为什么会有这样的行为,为什么接口允许这样的行为呢?
我相信这是因为演员阵容SomeClass
可以表示任意数量的事物,具体取决于可用的转换,而转换为ISomeInterface
只能是引用转换或装箱转换。
Options:
显然,在第二种情况下,您还需要事后执行无效检查,以防万一t
is not a SomeClass
.
编辑:C# 4 规范的第 6.2.7 节给出了这样做的原因:
上述规则不允许从不受约束的类型参数到非接口类型的直接显式转换,这可能会令人惊讶。制定此规则的原因是为了防止混淆并使此类转换的语义清晰。例如,考虑以下声明:
class X<T>
{
public static long F(T t) {
return (long)t; // Error
}
}
如果允许将 t 直接显式转换为 int,人们可能很容易想到:X<int>.F(7)
将返回 7L。但是,事实并非如此,因为只有在绑定时已知类型为数字时才会考虑标准数字转换。为了使语义清晰,上面的例子必须改为:
class X<T>
{
public static long F(T t) {
return (long)(object)t; // Ok, but will only work when T is long
}
}
该代码现在将编译但执行X<int>.F(7)
然后会在运行时抛出异常,因为装箱 int 不能直接转换为 long。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)