我不确定我是不是只是愚蠢......
如果我有一个界面:
public interface IMoop
{
object Moop();
}
为什么我不能这样实现它(我想这会使用隐式协方差?)
public class MoopImplementor : IMoop
{
string Moop();
}
MoopImplementor的任何实例都符合IMoop指定的合同,所以看起来这应该没问题。
请赐教:)
编辑:要清楚 - 因为实现类返回继承自Interfaced方法的返回类型的东西 - 我觉得这应该有效。具体而言,string
是object
。 (对于任何其他的衔接链也是如此)。
答案 0 :(得分:13)
为了接口实现或虚拟方法覆盖,C#不支持返回类型协方差。有关详细信息,请参阅此问题:
Does C# support return type covariance?
C#支持从C#4开始为类型参数的引用类型构造的接口和委托类型的通用协方差和逆变。
当将返回引用类型的方法转换为返回类型为兼容引用类型的委托类型时,C#支持返回类型协方差。(同样地,它支持参数类型逆变。)
如果这个主题让你感兴趣,我写了很多文章讨论C#所做和不支持的各种版本的差异。见
https://blogs.msdn.microsoft.com/ericlippert/tag/covariance-and-contravariance/
了解详情。
答案 1 :(得分:7)
因为接口指定方法必须返回object
。 string
可以继承自object
,但接口指定的方法返回更通用的类型。
请记住,没有什么可以阻止你做以下事情:
public object Moop()
{
return "Some new string";
}
答案 2 :(得分:4)
合理的解决方法:
public class MoopImplementor : IMoop {
public string Moop() { ... }
object IMoop.Moop() { return Moop(); }
}
这允许MoopImplementor
上的公共实现具有更准确的类型,同时仍满足界面的要求。
答案 3 :(得分:3)
您没有达成合同。但是,您可以使用泛型来执行此操作:
public interface IMoop<T>
{
T Moop();
}
public class MoopImplementor : IMoop<string>
{
public string Moop() { return ""; }
}
答案 4 :(得分:2)
出于接口映射的目的,类成员A匹配 接口成员B时:
- A和B是方法,名称类型,A和B的形式参数列表相同。
请注意,它没有说继承或可转换性!返回类型必须相同。