覆盖 C# subclass 而不必创建另一个 class?

Overriding C# subclass without having to create another class?

我已经从表单中子classed 按钮,因为这是我可以覆盖 OnClick 的唯一方法。

但现在我有几个按钮使用我的 SubButton class,我希望它们做不同的事情(换句话说,我希望它们的 Action() 方法做不同的事情)。

遗憾的是,我对之后如何覆盖它的 Action 方法一无所知,这里是 class 声明:

    class SubButton : Button
    {
        public void Action() { }

        protected override void OnClick(EventArgs e)
        {
            this.Action();
            base.OnClick(e);
        }
    }

这是我尝试过的:

apply.Action = { };

在此先感谢您的帮助!

为什么不通过构造函数注入简单地将 Action 作为委托传递:

class SubButton : Button
{
    private readonly Action action;
    public SubButton(Action action) { this.action = action; }


    protected override void OnClick(EventArgs e)
    {
        if (this.action != null) this.action();
        base.OnClick(e);
    }
}

现在这样称呼它:

var btn = new SubButton(() => Console.WriteLine("Hello World"));

另一个按钮什么也做不了:

var other = new SubButton(() => { });

这样您就不需要为每个新按钮创建一个新的 class,只需将 "what to do when clicking the button" 部分放入构造函数即可。

为了进一步说明 HimBromBeere 所说的内容,我已将代表作废。

您可以将 Action 作为构造函数中的委托传递。

class SubButton : Button
    {
        public delegate void DoAction();
        public DoAction Action;

        public SubButton(DoAction action)
        {
            this.Action = action;
        }

        protected override void OnClick(EventArgs e)
        {
            Action?.Invoke(); // null propogation, no need for if statements.
            base.OnClick(e);
        }
    }

然后像这样使用它:

var btn = new SubButton(() => Console.WriteLine("Hello World!"));

第一种方式,你如何根据 EventArgs e 选择你的动作。如果 e 发送了一些值,您应该创建自定义 EventArgs class,它具有 属性 给定值。 例如:

public class ActionEventArgs : EventArgs
{
    public ActionEventArgs(string valueName)
    {
        this.YourTypeValueName = valueName;
    }
    public YourType YourTypeValueName { get; set;}
}

此外,您应该像这样创建 CustomEventHandler:

public delegate void ActionEventHandler(object sender, ActionEventArgs args) 

然后,您可以为每个操作创建不同的方法,例如 ActionDoSth1()、ActionDoSth2 等。 将您的 OnClick 更改为接受 ActionEventArgs 而不是 EventArgs 和 然后你可以在 OnClick 中使用 switch,例如:

protected override void OnClick(ActionEventArgs e)
{
    switch(e.YourTypeValueName)
    {
        case sth1:
        {
            ActionDoSth1();
        }

        break;
        case sth1:
        {
            ActionDoSth2();
        }

        break;
        ...
        ...
    }

    base.OnClick(e);
}

第二种方法是使操作虚拟化,并为每个操作创建子按钮 class 子按钮,您可以根据需要在其中覆盖操作。 在这种情况下,您将针对每种情况使用不同的按钮,并且您不需要创建 ActionEventArgs。如果你想在一个 SubButton 中执行所有操作,请忽略此选项 class.