【问题标题】:Whether to extend interface, when base class already extends same interface是否扩展接口,当基类已经扩展同一个接口时
【发布时间】:2019-05-22 15:51:16
【问题描述】:

在 C# 中,如下面的代码 sn-p 所示,在声明类 A 时扩展接口 IFoo 是否正确/正确,知道类 BaseClass 扩展了接口 IFoo?此处是否需要指定接口IFoo,是最佳实践吗?

class A : BaseClass, IFoo
{
}

这可能是一个愚蠢的问题,但在这种情况下,适当的做法是什么?

【问题讨论】:

  • 在 C# 中,没有任何东西扩展接口,也没有任何东西继承接口。接口已实现。
  • 我想区分指定我想实现一个接口和实际实现它(它的方法)。
  • @itsme86 “没有继承接口” - 不正确。 "...Interfaces can inherit from other interfaces..."

标签: c# inheritance interface base-class interface-implementation


【解决方案1】:

如果 BaseClass 继承自 IFoo,则完全没有必要在 A 类中使用 IFoo。

查看下图(此推荐使用Resharper


特别感谢@InBetween

如果是接口重实现的话,在子类上重定义接口是有用例的。

interface IFace
{
    void Method1();
}
class Class1 : IFace
{
    void IFace.Method1()
    {
        Console.WriteLine("I am calling you from Class1");
    }
}
class Class2 : Class1, IFace
{
    public void Method1()
    {
        Console.WriteLine("i am calling you from Class2");
    }
}

int main void ()
{
    IFace ins = new Class2();
    ins.Method1();
}

此方法返回i am calling you from Class2

而,

interface IFace
{
    void Method1();
}
class Class1 : IFace
{
    void IFace.Method1()
    {
        Console.WriteLine("I am calling you from Class1");
    }
}
class Class2 : Class1
{
    public void Method1()
    {
        Console.WriteLine("i am calling you from Class2");
    }
}

int main void ()
{
    IFace ins = new Class2();
    ins.Method1();
}

返回I am calling you from Class1

【讨论】:

  • 虽然在 OP 问题的上下文中 100% 正确,但一般来说,这个答案并不总是正确的。有一个鲜为人知的语言特性,称为 interface reimplementation,其中需要重新声明接口。
  • 我刚刚看到您已经为您的评论添加了答案。我还编辑了我的答案,但如果你愿意,我可以回滚我的编辑
  • 不,没关系,别担心
【解决方案2】:

虽然在您的特定情况下接受的答案是正确的,但情况并非总是如此。

在类声明中重新声明接口可能有用且必要:当您想要重新实现接口时。

考虑以下代码,仔细研究:

interface IFoo {
    string Foo(); }

class A: IFoo {
    public string Foo() { return "A"; } }

class B: A, IFoo {
}

class C: A {  
    new string Foo() { return "C"; } }

class D: A, IFoo {
    string IFoo.Foo() { return "D"; } }

现在试着弄清楚下面的代码会输出什么:

IFoo a = new A();
IFoo b = new B();
IFoo c = new C();
IFoo d = new D();

Console.WriteLine(a.Foo());
Console.WriteLine(b.Foo());
Console.WriteLine(c.Foo());
Console.WriteLine(d.Foo());

您现在看到重新声明接口(类型D)有什么用了吗?

另外,要说明的另一个要点是 MSDN 中的信息可能会产生误导,似乎暗示许多接口在许多类中被重新声明而没有任何明显的原因;例如,许多集合类型重新声明了无限数量的接口。

这不是真的,问题是文档是建立在程序集的元数据之上的,并且该工具无法真正辨别接口是否直接在类型中声明。此外,因为它的文档明确地告诉您实现的接口,无论它们实际声明在哪里,即使它不是 100% 准确的源代码也是一个好处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    • 2012-12-07
    • 2023-03-20
    • 2017-01-21
    相关资源
    最近更新 更多