覆盖 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.
我已经从表单中子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.