12

可能重复:
C# 是否支持返回类型协方差?

我不确定我是否只是愚蠢...

如果我有一个界面:

public interface IMoop
{
    object Moop();
}

为什么我不能像这样实现它(我想这会使用隐式协方差?)

public class MoopImplementor : IMoop
{
    string Moop();
}

MoopImplementor 的任何实例都将满足 IMoop 指定的合同,所以看起来应该没问题。

请赐教:)

编辑:要清楚——因为实现类返回的东西继承自接口方法的返回类型——我觉得这应该可行。具体来说,一个string是一个object。(对于任何其他继承链也是如此)。

4

5 回答 5

13

C# 不支持用于接口实现或虚拟方法覆盖的返回类型协变。有关详细信息,请参阅此问题:

C# 是否支持返回类型协方差?

从 C# 4 开始,C# 确实支持使用类型参数的引用类型构造的接口和委托类型的泛型协变和逆变

And C# does support return type covariance when converting a method that returns a reference type to a delegate type whose return type is a compatible reference type. (And similarly it supports parameter type contravariance.)

If this subject interests you, I have written a great many articles discussing various versions of variance that C# does and does not support. See

https://blogs.msdn.microsoft.com/ericlippert/tag/covariance-and-contravariance/

for details.

于 2012-04-26T17:21:20.957 回答
7

因为接口指定方法必须返回一个object. Astring可以继承自object,但接口指定了一个返回更通用类型的方法。

但是请记住,没有什么可以阻止您执行以下操作:

public object Moop()
{
    return "Some new string";
}
于 2012-04-26T17:03:12.120 回答
4

一个合理的解决方法:

public class MoopImplementor : IMoop {
  public string Moop() { ... }
  object IMoop.Moop() { return Moop(); }
}

这允许公共实现MoopImplementor具有更准确的类型,同时仍然满足接口的要求。

于 2012-04-26T17:07:57.223 回答
3

你没有履行合同。但是,您可以使用泛型执行此操作:

public interface IMoop<T>
{
    T Moop();
}

public class MoopImplementor : IMoop<string>
{
    public string Moop() { return ""; }
}
于 2012-04-26T17:05:51.797 回答
2

来自C# 语言规范

13.4.4 接口映射

出于接口映射的目的,类成员 A 在以下情况下与接口成员 B 匹配:

  • A 和 B 是方法,A 和 B 的名称、类型和形参列表相同

请注意,它没有说明继承或可转换性!返回类型必须相同。

于 2012-04-26T17:19:56.663 回答