重写C#子类而不必创建另一个类?

时间:2016-09-19 10:38:04

标签: c# subclass override

我已经从表单中继承了Button,因为这是我可以覆盖OnClick的唯一方式。

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

可悲的是,我对如何覆盖它后面的Action方法一无所知,这里有类声明:

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

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

以下是我的尝试:

apply.Action = { };

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

为什么不通过constructor-injection简单地将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(() => { });

这样你就不需要为每个新按钮创建一个新类,只需将“点击按钮时该做什么” - 部分放入构造函数中。

答案 1 :(得分:0)

为了扩展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!"));

答案 2 :(得分:0)

首先,您如何根据EventArgs e选择行动。如果e发送了一些值,您应该创建自定义EventArgs类,该类具有给定值的属性。 例如:

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中使用开关,例如:

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

        break;
        case sth1:
        {
            ActionDoSth2();
        }

        break;
        ...
        ...
    }

    base.OnClick(e);
}

第二种方法是使动作成为虚拟动作,并为每个动作创建SubButton的子类,您可以根据需要覆盖Action。 在这种情况下,每种情况都有不同的按钮,您不需要创建ActionEventArgs。如果您想要在一个SubButton类中执行所有操作,请忽略此项。