首页 > 解决方案 > 多接口继承在 C# 中如何工作?

问题描述

我正在学习ASP.NET Core 2,我想到了一个问题。Interface实例如何给出不同的实现?

让我们得到IServiceCollection。它有各种方法,如AddMvc(), AddDbContext<T>()等。如果有人实现它,检查源代码 IServiceCollection没有任何必须实现的方法。它只是继承IList<ServiceDescriptor>和继承链IList < ICollection < IEnumerable

好的,去看看ServiceDescriptor,但是该类没有实现任何interface方法,并且其中没有类似的方法实现AddMvc(), AddDbContext<T>

那么这些方法是如何以及从哪里来的呢?它在幕后如何运作?

我真的很想学习 OOP,但我想我错过了一些基础知识。

标签: c#oop

解决方案


这里的诀窍是接口可以附加额外的方法。在 C# 中,我们使用扩展方法来做到这一点。这是一个基本示例:

public interface IFoo 
{
    int GetFoo();
}

public class Foo : IFoo 
{
    public int GetFoo()
    {
        var foo = ... // does something to get a foo
        return foo;
    }
}

public class Program
{
    public static void Main()
    {
        IFoo theFoo = new Foo();
        theFoo.PityTheFoo();       // wait, what?  
    }
}

现在在这一点上,我可以听到你在说“艾米!坚持IFoo住!没有任何方法可以做任何怜悯!” 你是对的。假装您不拥有IFoo. 你怎么能添加一个方法IFoo?或者,假设您确实拥有 的源代码IFoo,并且想要添加一个方法而不必修改实现该接口的每个类?

这就是扩展方法的用武之地:

public static class FooExtensions 
{
    public static void PityTheFoo(this IFoo foo)
    {
        // pities the foo
    }
}

注意this函数声明中的关键字。这表明这是一种扩展方法。它将我们的PityTheFoo方法附加到接口上。实现IFoo接口的类不需要实现PityTheFoo()。如果你有一百个不同的Foo类,都实现了这个接口,那么它们都不需要修改。

扩展方法不是继承链的一部分。当编译器到达 中的注释行时Program,这就是它“假装”代码的样子:

public class Program
{
    public static void Main()
    {
        IFoo theFoo = new Foo();
        FooExtensions.PityTheFoo(theFoo);
    }
}

我们为什么要这个?

  • 您不拥有该接口,但想向其添加操作。
  • 您拥有该接口,但实现该接口的众多类可以共享相同的实现,有点像它们继承了它。
  • 该接口可能是库的一部分。如果您向其中添加方法,使用您的库的人会发现他们的代码被破坏,直到他们将该方法添加到他们的类中。扩展方法可让您避免重大更改。

推荐阅读