我知道我错过了一些东西,但这不应该奏效吗!?
public interface IFoo<out TA, in TB>
where TA : class
where TB : class
{
}
public class Foo<T> : IFoo<T, T> where T : class { }
public class Whatever { }
Foo<Whatever> _Foo = new Foo<Whatever>(); // (changed "Foo" to "_Foo to be more clear)
var f = (IFoo<object, object>)_Foo; // CAST ERROR
仅供参考:最初的项目是。NET 4.0使用VS 2013。
编辑:看来"TB"参数(方差)的"in"类型必须是SAME类型或DERIVED类型。由于"object"是超类型(如中,"object"不是从类型"Whatever"派生的),因此转换失败。(感谢Aasmund Eldhuset)
这确实有效:
public class WhateverB : Whatever { }
var f = (IFoo<object, WhateverB>)Foo; // YAY ;)
Foo<string>
是而不是IFoo<object, object>
,因为泛型类型参数TB
不匹配-对于in
泛型类型参数,实际类型必须等于或是泛型类型参数的超类,但string
不是object
的超类。
编译器接受强制转换的原因是,对接口类型的强制转换几乎总是合法的(PetSerAl提到的角落情况除外),因为可能是您从中强制转换的类型的某个子类实现了接口。