c# - 我应该将属性声明为接口(interface)还是基类(当它们同时实现时)?

标签 c# inheritance interface casting

我有一个类以类似的方式使用一组属性(为简洁起见,示例中仅显示了两个属性)。 一般行为是在基类上定义的,而特定行为是在特定接口(interface)中定义的

问题是:如果我将它们声明为基类,我必须将它们转换为接口(interface)才能调用接口(interface)方法。现在,如果我将它们声明为接口(interface),当我想调用基方法时,我必须将它们转换为基类。

我在这里使用接口(interface)的目标是提高可测试性(稍后使用依赖注入(inject)),并培养“向接口(interface)编程”的习惯,但我无法决定哪种方式是最好的,或者即使整个理由是首先很好。

public class Conductor
{
    // These properties inherit from base class
    // and implement one specific interface each:

    // declared as interface:
    IPlotterHelper  _plotter_helper = new PlotterHelper();

    // declared as base class:
    Helper _file_writer_helper = new FileWriterHelper();


    // When using handlers defined in specific interfaces:

    // have to cast this:
    this.NewFrame   += ((IPlotterHelper)_file_writer_helper).ProcessFrame();

    // but not this:
    this.NewSamples += _plotter_helper.ProcessSamples();



    // While when using handlers from the base class

    // have to cast this to the base class (since it is an interface):
    this.CommandSent += ((Helper)_plotter_helper).RunCommand;

    // but not this:
    this.CommandSent += _file_writer_helper.RunCommand;
}



internal class FileWriterHelper : Helper, IFileWriterHelper
{
    IFileWriterHelper.ProcessFrame()
    {
        // ...
    }

    // ...
}

internal class PlotterHelper : Helper, IPlotterHelper
{
    IPlotterHelper.ProcessSamples ()
    {
        ///
    }

    // ...
}

internal class Helper
{
    internal void RunCommand()
    {
        // ...
    }
}

最佳答案

当我希望在接口(interface)中具有默认行为时,我通常会考虑使用带有 protected 辅助方法和一组抽象接口(interface)方法的抽象基类,或者使用“接口(interface)”方法的默认实现。即使我只从一个具体实现开始,情况也可能是这样。

许多人将抽象类和接口(interface)视为同一广泛的实现选项类别。

抽象类的问题是单继承,因此只有当抽象类确实是类层次结构的基础(即使是浅层层次结构)时,我们才应该使用它。接口(interface)可用于装饰具有共同行为的类(来自不同的层次结构)。

对于测试,我认为使用接口(interface)进行伪造和使用抽象类进行伪造之间没有太大区别 - 但这可能取决于您的测试基础设施。

在这种情况下,我将使用抽象类并忘记接口(interface)(除非它已经存在,在这种情况下你无论如何都没有任何选择)。

关于c# - 我应该将属性声明为接口(interface)还是基类(当它们同时实现时)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34304766/

相关文章:

c# - 查找字符串中字符的索引

c# - 仅在 asp.net 中的 Convert.ToDateTime() 中获取日期

实现匿名函数的匿名接口(interface)的java语法

java - 为什么必须在 Java 中声明接口(interface)?

c# - 响应式(Reactive) UI + WPF : Binding to 'ItemsSource' not working as expected

c# - Response.redirect 不在 c# 中重定向

C++ 覆盖嵌套类只能部分说服编译器

java - 如何覆盖具有默认(包)可见性范围的方法?

c++ - 调用父类(super class)构造函数的规则是什么?

c# - 声明不属于我的类符合 C# 接口(interface)