C# 抽象函数可以实现吗?

发布于 2024-11-25 17:21:38 字数 173 浏览 0 评论 0原文

有没有办法添加一个必须被所有继承类重写的虚函数?那么实际上是虚拟与抽象的结合吗? 我遇到的情况是,每个继承的类都必须在执行某些通用代码之前进行一些特定的处理。虚函数不起作用,因为它们不能确保继承的类覆盖它们。并且抽象函数不能有默认实现。目前我的解决方法是在基类中实现另一个受保护的函数,其中包含公共/通用代码并在重写的抽象函数中调用

Is there a way to add a virtual function that must be overridden by all inherited classes? So actually the combination of virtual and abstract?
I have a situation where each inherited class must do some specific processing before some generic code is executed. Virtual functions doesn't work because they do not ensure the inherited classes override them. And abstract function can't have a default implementation. Currently my workaround is to implement another protected function in the base class which contains the common/generic code and is called in the overridden abstract function

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

君勿笑 2024-12-02 17:21:38

不可能有一个既抽象又虚拟的方法。

如果可能,您可以将方法分为“之前”和“之后”部分:

public void DoWork()
{
    DoBeforeWork();
    DoCommonWork();
    DoAfterWork();
}

protected abstract void DoBeforeWork();
protected abstract void DoAfterWork();

private void DoCommonWork() { ... }

否则,使用第二个受保护方法的解决方法是一个非常好的主意:

public void DoWork()
{
    DoActualWork();
}

protected abstract void DoActualWork(); // expected to call DoCommonWork

protected void DoCommonWork() { ... }

您可以使用线程本地字段检查 DoCommonWork 是否确实在 DoWork 中调用如果需要的话。

但是,我可能会选择将该方法虚拟化。如果派生类不想向公共部分添加任何内容,则不必这样做:

public virtual void DoWork() { ... }

同样,您可以检查公共部分是否真正被调用。

It is not possible to have a method that is both abstract and virtual.

If possible, you can split your method in a "before" and "after" part:

public void DoWork()
{
    DoBeforeWork();
    DoCommonWork();
    DoAfterWork();
}

protected abstract void DoBeforeWork();
protected abstract void DoAfterWork();

private void DoCommonWork() { ... }

Otherwise, your workaround with a second protected method is a very good idea:

public void DoWork()
{
    DoActualWork();
}

protected abstract void DoActualWork(); // expected to call DoCommonWork

protected void DoCommonWork() { ... }

You can check if DoCommonWork was really called in DoWork using a thread-local field if necessary.

However, I'd probably go with making the method virtual. If the derived class doesn't want to add anything to the common part, it shouldn't have to:

public virtual void DoWork() { ... }

Again, you can check if the common part was really called.

我ぃ本無心為│何有愛 2024-12-02 17:21:38

我认为您可能正在寻找模板方法:在基类中实现一个调用抽象方法作为其实现的一部分。然后派生类可以实现抽象方法,但这允许基类在执行该方法之前进行“一些特定处理”。

I think you might be looking for a template method: Implement a method in your base class that calls an abstract method as part of its implementation. Derived classes then can implement the abstract method, but this allows the base class to do "some specific processing" before this method is executed.

只有一腔孤勇 2024-12-02 17:21:38

我的建议是将基类分为两类:一类是抽象类,一类是具体密封类。

示例

我假设您有如下所示的基类:

public class BaseClass
{
    public void DoProcessing()
    {
        // this method must be overriden in each subclass
    }
}

让我们将其分成两部分:

public abstract class BaseClass
{
    protected abstract DoProcessingImlementation();    

    public void DoProcessing()
    {
        // here you can add program logic or just call overridden implementation
        DoProcessingImplementation();
    }
}

public sealed class DefaultBaseClassImplementation : BaseClass
{
    public override DoProcessingImlementation()
    {
        // default implementation of method
    }
}

使用此设计,如果您需要实现新的处理逻辑,您可以从 BaseClass 继承新类,因为它是抽象的必须实现 DoSomethigImplementation 方法。要访问默认处理逻辑,您应该使用 DefaultBaseClassImplementation 类的实例。而且 DefaultBaseClassImplementation 是密封的,不会让您从错误的类继承。

My suggestion is to split the base class into two: classes one abstract and one concrete sealed.

Example

I assume that you have base class which looks like that:

public class BaseClass
{
    public void DoProcessing()
    {
        // this method must be overriden in each subclass
    }
}

Let's split it to two:

public abstract class BaseClass
{
    protected abstract DoProcessingImlementation();    

    public void DoProcessing()
    {
        // here you can add program logic or just call overridden implementation
        DoProcessingImplementation();
    }
}

public sealed class DefaultBaseClassImplementation : BaseClass
{
    public override DoProcessingImlementation()
    {
        // default implementation of method
    }
}

With this design if you need to implement new processing logic, you inherit new class from the BaseClass and because it's abstract you must implement the DoSomethigImplementation method. To access the default processing logic you should use an instance of the DefaultBaseClassImplementation class. And that the DefaultBaseClassImplementation is sealed will not let you inherit from the wrong class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文