【问题标题】:Interface referencing another interface but class referencing another class in C#接口引用了另一个接口,但类引用了 C# 中的另一个类
【发布时间】:2013-05-03 10:53:26
【问题描述】:

我有一个很简单的问题,但是我以前没有遇到过这个问题。

看看这段代码:

interface IFoo
{
    IBar MyBar { get; }
}

interface IBar
{
    String Test { get; }
}

class Foo : IFoo
{
    public Bar MyBar { get; set; }
}

class Bar : IBar
{
    public String Test { get; set; }
}

问题在于 Foo 没有实现 IFoo,因为它返回 Bar 而不是 IBar。但我没有看到问题,因为 Bar 正在实施 IBar。我错过了什么吗?

我希望我的应用程序使用 Foo 类,但将 IFoo 暴露给解决方案的其他部分。

这是一种解决方法,但它似乎是一个丑陋的解决方案:

class Foo : IFoo
{
    public Bar MyBar { get; set; }
    IBar IFoo.MyBar { 
        get { return this.MyBar; }
    }
}

这是要走的路,还是更好的路?

【问题讨论】:

  • BarIBar,但 IBar 不是 Bar
  • 这称为返回类型协方差,根据this post C#,CLR 不支持。
  • “丑陋的方法”(也称为显式接口实现)确实是 C# 中解决此问题的唯一方法。事实上,这也是该功能存在的部分原因。
  • 我认为您的解决方案(显式接口)是我的首选方式。另一个选择,因为你只有吸气剂是使用out 泛型:interface IFoo<out T> where T : IBar { T MyBar { get; } },然后你可以分配像:IFoo<IBar> f = new Foo(); 这样的 foo,但这很糟糕,因为你有这个无用的泛型一直在浮动。

标签: c#


【解决方案1】:

你可以这样做:

interface IFoo<out B> where B:IBar
{
    B MyBar { get; }
}

interface IBar
{
    String Test { get; }
}

class Foo : IFoo<Bar>
{
    public Bar MyBar { get; set; }
}

class Bar : IBar
{
    public String Test { get; set; }
}

这仅适用于B 处于输出位置的情况(出于显而易见的原因,如果您考虑足够长的时间)。

【讨论】:

    【解决方案2】:

    问题在于 Foo 没有实现 IFoo,因为它返回 Bar 而不是 IBar。但我没有看到问题,因为 Bar 正在实施 IBar。我错过了什么吗?

    是的。您误解了 IFoo 接口的合同。合约很简单:

    一个名为 MyBar 的属性,它有一个 getter,返回类型为 IBar。 约定不是它返回一个 IBar 类型的对象,而是返回类型是输入 IBar。

    这是标准的。尝试实现ICloneable 接口,它有一个方法Clone(),返回类型为object。实现这个接口意味着无论如何你都必须实现一个返回类型为object的方法。即使您希望更具体一点,任何其他返回类型都不符合条件。

    您建议的解决方法是正确的方法之一 - 拥有一个返回 Bar 属性的 IBar 属性。或者,您知道,您可以只拥有一个 IBar 属性并将其设置为 Bar 实例,因为这是完全有效的,然后通过 IBar 合同使用您的 IBar 对象。这将有助于解耦。

    【讨论】:

      猜你喜欢
      • 2016-04-28
      • 2023-01-10
      • 2012-04-30
      • 2021-12-14
      • 2011-06-09
      • 1970-01-01
      • 2022-11-28
      • 2015-03-10
      • 2021-07-22
      相关资源
      最近更新 更多