Inc*_*ito 38 .net c# generics clr
在泛型FAQ中:最佳实践说:
编译器将允许您将泛型类型参数显式转换为任何接口,但不能转发给类:
interface ISomeInterface
{...}
class SomeClass
{...}
class MyClass<T>
{
void SomeMethod(T t)
{
ISomeInterface obj1 = (ISomeInterface)t;//Compiles
SomeClass obj2 = (SomeClass)t; //Does not compile
}
}
Run Code Online (Sandbox Code Playgroud)
除非未将类/接口指定为约束类型,否则我认为类和接口的限制都是合理的.
那么为什么这样的行为,为什么它被允许接口呢?
Jon*_*eet 53
我相信这是因为演员SomeClass可以表示任意数量的事情取决于可用的转换,而演员ISomeInterface只能是参考转换或拳击转换.
选项:
首先转换为对象:
SomeClass obj2 = (SomeClass) (object) t;
Run Code Online (Sandbox Code Playgroud)as改为使用:
SomeClass obj2 = t as SomeClass;
Run Code Online (Sandbox Code Playgroud)显然,在第二种情况下,你还需要在以后的情况下进行无效检查t是不是一个SomeClass.
编辑:对此的推理在C#4规范的第6.2.7节中给出:
上述规则不允许从无约束类型参数直接显式转换为非接口类型,这可能是令人惊讶的.此规则的原因是为了防止混淆并使这种转换的语义清晰.例如,请考虑以下声明:
Run Code Online (Sandbox Code Playgroud)class X<T> { public static long F(T t) { return (long)t; // Error } }如果允许将t直接显式转换为int,则可能很容易预期
X<int>.F(7)会返回7L.但是,它不会,因为仅在绑定时已知类型为数字时才考虑标准数字转换.为了使语义清晰,必须编写上面的示例:Run Code Online (Sandbox Code Playgroud)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)会在运行时抛出异常,因为boxed int无法直接转换为long.
| 归档时间: |
|
| 查看次数: |
33649 次 |
| 最近记录: |