【问题标题】:Can we replace abstract class with Interface with Default Methods in C#我们可以用 C# 中的默认方法用接口替换抽象类吗
【发布时间】:2019-12-12 07:02:19
【问题描述】:

在 C# 8.0 中,我们有一个新功能,我们可以在接口中提供默认方法实现,也可以被其实现类覆盖。

我们曾经使用带有实例方法的抽象类来为其所有实现类提供通用功能。

现在我可以将那些具有实例方法的抽象类替换为具有从 C# 8.0 开始的默认方法实现的接口吗?

【问题讨论】:

  • 如果你能提供minimal reproducible example就太好了
  • 在哪些情况下更换它们?接口仍然是接口,即使它们可以有代码。它们不能保持状态、处理事件或创建继承关系。如果你有引入is-a关系的纯方法抽象类,那么也许你可以使用DIM。发布您的代码

标签: oop c#-8.0 default-interface-member


【解决方案1】:

不,抽象类仍然占有一席之地。特别是,抽象类可以声明字段(现在通常通过自动实现的属性),而接口仍然不能。他们还可以定义构造函数,并在其中执行验证。

这是一个你不能用接口做的事情的例子:

public abstract class NamedObject
{
    public string Name { get; }

    protected NamedObject(string name) =>
        Name = name ?? throw new ArgumentNullException(nameof(name));

    // Abstract methods here
}

显然它不会真的被称为NamedObject - 有一个特定于业务的原因使其抽象,这将决定名称。但是这里的行为是不能放在接口中的行为。

【讨论】:

  • 事件是另一个问题,因为它们由委托字段支持。为INotifyPropertyChanged 创建一个特征会非常有用,但没有办法(据我所知)来实现该事件
【解决方案2】:

在大多数情况下可以,但可能不应该。接口中的默认功能是为了解决另一个问题。

当您无法更改现有类时,例如在某个其他项目/库中,并且您想扩展功能而不用抽象类更改所有代码时,它就在那里。..

也许作为一个抽象类有意义?具有行为但本身没有意义并且必须扩展的对象应该由类更好地建模。如果您有具有行为的 Car 类,那么您可以拥有适用于所有汽车的长度私有成员。私有成员不是接口的一部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-12
    • 2015-11-27
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多