在c#中,接口引用另一个接口,而类引用另一个类
本文关键字:另一个 引用 接口 | 更新日期: 2023-09-27 18:11:53
我有一个很简单的问题,但是我以前从来没有遇到过这个问题。
看一下这段代码:
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; }
}
}
这是正确的方法,还是更好的方法?
你可以这样做:
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
处于输出位置的情况下才有效(原因很明显,如果您考虑的时间足够长)。
问题是Foo没有实现IFoo,因为它返回Bar而不是IBar。但我不觉得有什么问题,因为Bar正在实现IBar。我错过什么了吗?
是的。你误解了IFoo接口的契约。合同很简单:
一个名为MyBar的属性,它有一个getter, 有一个返回类型IBar。约定不是它返回一个IBar类型的对象,而是返回类型为IBar。
这是标准的。尝试实现ICloneable
接口,它只有一个方法Clone()
,返回类型为object
。实现这个接口意味着无论如何必须实现一个返回类型为object
的方法。即使您想更具体一点,任何其他返回类型都不符合条件。
你建议的绕过它的方法是正确的方法之一——使用一个返回Bar属性的IBar属性。或者,你可以有一个IBar属性并设置它为一个Bar实例,因为那是完全有效的,然后通过IBar契约与你的IBar对象一起工作。这将有助于脱钩。