协方差和逆变换转换失败

时间:2015-03-31 21:57:58

标签: c# covariance contravariance

我知道我错过了什么,但不应该这样做!?

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

仅供参考:原始项目是使用VS 2013的.NET 4.0。

编辑:“TB”参数(逆向)的“输入”类型似乎必须是SAME类型或DERIVED类型。由于'object'是超类型(因为'object'不是从'Whatever'类型派生的),转换失败。 (感谢Aasmund Eldhuset)

这确实有效:

public class WhateverB : Whatever { }
var f = (IFoo<object, WhateverB>)Foo; // YAY ;)

1 个答案:

答案 0 :(得分:3)

Foo<string> IFoo<object, object>,因为通用类型参数TB不匹配 - 对于in通用type参数,实际类型必须等于或是泛型类型参数的超类,但string不是object的超类。

编译器接受强制转换的原因是对接口类型的强制转换几乎总是合法(除了PetSerAl提到的极端情况),因为它可能是某些子类的你实施界面的类型。