为什么我无法将Foo<Bar>
转换为IFoo<IBar>
。
如果我尝试我得到:
从
没有隐式引用转换Foo<Bar>
到IFoo<IBar>
答案 0 :(得分:12)
如果您使用C#4并且IFoo
被声明为:
public interface IFoo<out T>
假设Bar
实施IBar
而Foo<T>
实施IFoo<T>
。
然而,如果它是安全的,它只能被宣布。如果T
值“进入”API以及即将发布,那么不是安全的。例如:
public interface IFoo<T>
{
T Value { get; set; }
}
这个不能在T中协变,否则你可以写:
public class StringFoo : IFoo<string>
{
public T Value { get; set; }
}
IFoo<string> fooString = new StringFoo(); // That's fine
IFoo<object> fooObject = fooString; // This isn't, because...
fooObject.Value = new Object(); // ... this would violate type safety
阅读Eric Lippert的long blog series on generic variance以获取更多信息。
答案 1 :(得分:2)
为了实现这一点,需要做三件事:
Bar
必须实施IBar
Foo
必须实施IFoo
IFoo<T>
必须在T
中具有协变性(例如:IFoo<out T>
)答案 2 :(得分:1)
这取决于您正在编译的C#的版本。
C#和.NET 4引入了通用协方差和逆变:http://msdn.microsoft.com/en-us/library/dd799517.aspx