rob*_*rob 28 c# generics casting .net-4.0 contravariance
我正在尝试施放逆变委托但由于某种原因我只能使用"as"运算符.
interface MyInterface { }
delegate void MyFuncType<in InType>(InType input);
class MyClass<T> where T : MyInterface
{
public void callDelegate(MyFuncType<MyInterface> func)
{
MyFuncType<T> castFunc1 = (MyFuncType <T>) func; //Error
MyFuncType<T> castFunc2 = func as MyFuncType<T>;
MyFuncType<T> castFunc3 = func is MyFuncType<T> ? (MyFuncType<T>)func : (MyFuncType<T>)null; //Error
}
}
Run Code Online (Sandbox Code Playgroud)
castFunc2工作正常,但castFunc1和castFunc3导致错误:
Cannot convert type 'delegateCovariance.MyFuncType<myNamespace.MyInterface>' to myNamespace.MyFuncType<T>'
Run Code Online (Sandbox Code Playgroud)
在上为运营商MSDN文章指出,castFunc2和castFunc3"等价于"所以我不明白怎么只有一个可能会导致错误.另一部令我困惑的是将MyInterface从接口更改为类可以消除错误.
任何人都可以帮我理解这里发生了什么?谢谢!
Jos*_*eld 15
添加一个约束,使T必须是一个类.
class MyClass<T> where T: class, MyInterface
Run Code Online (Sandbox Code Playgroud)
这为编译器提供了足够的信息来知道T是可转换的.您也不需要显式转换.
差异仅适用于参考类型.T被允许是没有约束的值类型,这破坏了编译器证明T与逆变量兼容的能力.
第二个语句起作用的原因是因为as实际上可以执行空转换.例如:
class SomeClass { }
interface SomeInterface { }
static void Main(string[] args)
{
SomeClass foo = null;
SomeInterface bar = foo as SomeInterface;
}
Run Code Online (Sandbox Code Playgroud)
Foo显然不能直接转换为SomeInterface,但它仍然成功,因为仍然可以进行空转换.对于大多数情况,您的MSDN参考可能是正确的,但生成的IL代码非常不同,这意味着它们从技术角度来看根本不同.
| 归档时间: |
|
| 查看次数: |
721 次 |
| 最近记录: |