繁体   English   中英

向从 C# 接口继承的类添加通用方法?

[英]Add common method to classes inheriting from a C# Interface?

我有一个这样的界面:

    public interface ITestInterface
    {
        int a { get; set; }

        void DoSomething();
    }

我的一些类是从这个接口派生的:

    public class OneClass : ITestInterface
    {
        public int a { get; set; }

        public void DoSomething()
        {
            Console.WriteLine(this.a.ToString());
        }
    }

    public class AnotherClass : ITestInterface
    {
        public int a { get; set; }

        public void DoSomething()
        {
            Console.WriteLine((this.a * 2).ToString());
        }
    }

由于我现在需要在从我的接口派生的所有类上使用(大型)通用方法,因此我试图为此提供一个额外的基础 class:

 public class MyBaseClass
    {
        public void LargeCommonMethod()
        {
            Console.WriteLine((this.a * 3).ToString()); // no 'a' on base class
        }
    }

这显然不起作用,因为基础 class 还需要实现我的接口才能了解a字段。

我现在问自己最好的方法是什么:

  • MyBaseClassITestInterface继承?
  • LargeCommonMethod()设置为protected并通过 arguments 提供它使用的所有内部数据? (实际上有很多这样的..)
  • 一直跳过接口并用抽象基础 class 替换它?
  • ...?

C# 8 正好为这种情况提供了一个功能。

  • 你的类都实现了一个接口
  • 你想给接口添加一个方法
  • 您不希望对所有现有类进行重大更改。 如果向接口添加方法,所有类都会中断,除非您找到某种方法将方法添加到所有类。 (这包括修改它们以从新的基础 class 继承。)

该功能是默认接口方法

您可以将您的方法和默认实现添加到接口:

public interface ITestInterface
{
    int a { get; set; }

    void DoSomething();

    void LargeCommonMethod()
    {
        Console.WriteLine((this.a * 3).ToString());
    }
}

您现有的实现该接口的类不会中断。 当转换为接口时,您将能够调用接口中定义的方法。 您仍然可以修改任何 class 以提供自己的实现,覆盖接口的默认实现。

要使该方法可用,必须将 object 转换为接口 - ITestInterface

许多开发人员——包括我自己——发现这是一个奇怪的功能。 但这是它的场景。

一些文档

最常见的场景是将成员安全地添加到已被无数客户端发布和使用的接口中。

如果您需要方法的基本实现,那么接口显然不是 go 的方式。

我会选择一个抽象的 class 代替并摆脱接口。 基本上没有必要使设计复杂化。

当您希望保持 ITestInterface 一致时,适配器模式可能适合您的用例:

public interface ITestInterface
{
    int a { get; set; }

    void DoSomething();
}

public class TestInterfaceAdapter : ITestInterface
{
    private readonly ITestInterface _testInterface;

    public int a {
        get => _testInterface.a;
        set => _testInterface.a = value;
    }

    public TestInterfaceAdapter(ITestInterface testInterface)
    {
        _testInterface = testInterface;
    }

    public void DoSomething()
    {
        _testInterface.DoSomething();
    }

    public void LargeCommonMethod()
    {
        Console.WriteLine((this.a * 3).ToString());
    }
}

public class OneClass : ITestInterface
{
    public int a { get; set; }

    public void DoSomething()
    {
        Console.WriteLine(this.a.ToString());
    }
}

public class AnotherClass : ITestInterface
{
    public int a { get; set; }

    public void DoSomething()
    {
        Console.WriteLine((this.a * 2).ToString());
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM