C# 我应该将属性声明为接口还是基类(当它们实现两者时)?

C# 我应该将属性声明为接口还是基类(当它们实现两者时)?,c#,inheritance,interface,casting,C#,Inheritance,Interface,Casting,我有一个类以类似的方式使用一组属性(为了简洁起见,示例中只显示了两个)。 一般行为在基类上定义,而特定行为在特定接口中定义 问题是:如果我将它们声明为基类,我必须将它们转换为接口来调用接口方法。现在,若我将它们声明为接口,当我想要调用基类方法时,我必须将它们转换为基类 在这里使用接口时,我的目标是提高可测试性(稍后使用依赖项注入),并培养“向接口编程”的习惯,但我无法决定哪种方式是最好的,甚至无法决定整个原理是否是好的 public class Conductor { // These

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

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

在这里使用接口时,我的目标是提高可测试性(稍后使用依赖项注入),并培养“向接口编程”的习惯,但我无法决定哪种方式是最好的,甚至无法决定整个原理是否是好的

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()
    {
        // ...
    }
}

很难准确地看到您正在尝试做什么,但似乎这可能是一个更合适的设计:

public class Conductor
{
    private IPlotterHelper _plotter_helper = new PlotterHelper();

    private IFileWriterHelper _file_writer_helper = new FileWriterHelper();

    public void Conduct()
    {
        _file_writer_helper.ProcessFrame();
        _file_writer_helper.RunCommand();
        _plotter_helper.ProcessSamples();
        _plotter_helper.RunCommand();
    }
}

internal interface IHelper
{
    void RunCommand();
}

internal interface IFileWriterHelper : IHelper
{
    void ProcessFrame();
}

internal interface IPlotterHelper : IHelper
{
    void ProcessSamples();
}


internal class FileWriterHelper : Helper, IFileWriterHelper
{
    public void ProcessFrame()
    {
    }
}

internal class PlotterHelper : Helper, IPlotterHelper
{
    public void ProcessSamples()
    {
    }
}

internal class Helper : IHelper
{
    public void RunCommand()
    {
    }
}

当我面临接口中默认行为的愿望时,我通常会考虑使用一个抽象基类,要么使用受保护的助手方法,要么使用一组抽象接口方法或“接口”方法的默认实现。即使我只从一个具体的实现开始,情况也可能如此

许多人将抽象类和接口视为同一大类的实现选项

抽象类的问题是单一继承,因此,如果抽象类真的要作为类层次结构的基础(即使是浅层次结构),我们应该只使用抽象类。接口可以用来装饰具有共同行为的类(来自不同层次结构)

对于测试,我看不出使用接口伪造与使用抽象类伪造之间有多大区别,但这可能取决于您的测试基础架构


在这种情况下,我将使用一个抽象类,而忽略接口(除非它已经存在,在这种情况下,您没有任何选择)。

接口和抽象类的目的相同:提供抽象。确保抽象一致,如果基类有公共成员,确保它们也在接口上


但是,为什么我需要抽象类或接口呢正确的。不管是基类还是接口,你都不需要。我会删除基类。

仅供参考,在命名变量时,我不会使用下划线,除非在开头(表示它们是字段)
\u plotter\u helper
是错误的,应该是
\u plotter helper
等等。你所说的“特定行为在特定接口中定义”是什么意思,因为接口不定义行为?如果你发布的代码能够真正编译,那也太棒了。“现在是狗的早餐。”我表达得很糟糕。我想说的是“多态性”,即每个接口实现者将以不同的方式实现给定的方法。谢谢你的回答!我想我在解释时没有说清楚,但事实是:
RunCommand
Helper
中定义了一个通用的实现(现在我想这是一个非常糟糕的名字)。之所以这样命名,是因为指挥给它发出命令,以便它“帮助”执行协调一致的动作(与其他助手一起)。但是每个专门的助手也有专门的成员来做额外的事情(如
ProcessSamples
ProcessFrames
,这些东西与命令运行功能分离。哇,那太好了!即使现在我正在解决这个问题,我相信这完全正确地回答了问题。谢谢!好吧,这就是我最后要做的。我不是
IPlotterHelper
,而是我有一个直接的
PlotterHelper
子类,所以我不必再回到
Helper
了。谢谢!