我正在研究代表们。几天前,我为多播代表做了一个示例,并在这里进行了审核My previous question,并清楚地了解了多播委托。
但是现在我尝试用事件做多播委托示例。但在做样品时我有些疑惑。在上面的链接中,我在一个类中完成了所有函数和委托声明,并使用+ =将函数添加到委托中,并且只需调用委托。所以调用了委托中的所有函数。
但现在我在两个不同的类中进行,并尝试在事件的帮助下完成所有功能。我在下面提供我目前的代码。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ArithmeticOperations aOperations = new ArithmeticOperations();
aOperations.StartCalculations += new ArithmeticOperations.BasicCalculations(aOperations_StartCalculations);
aOperations.PerformCalculations(20, 10);
}
void aOperations_StartCalculations(string msg)
{
MessageBox.Show(msg);
}
}
class ArithmeticOperations
{
public delegate void BasicCalculations(string msg);
public event BasicCalculations StartCalculations;
public void PerformCalculations(int n1, int n2)
{
StartCalculations("Operation Success");
}
void Add(int num1, int num2)
{
MessageBox.Show("Performing addition.");
}
void Sub(int num1, int num2)
{
MessageBox.Show("Performing substraction.");
}
void Mul(int num1, int num2)
{
MessageBox.Show("Performing multiplication.");
}
void Div(int num1, int num2)
{
MessageBox.Show("Performing division.");
}
}
这里Form1是我的主类,ArithmeticOperations类用于执行功能。在此声明中
aOperations.PerformCalculations(20, 10);
在Form1中,将执行ArithmeticOperations类中的PerformCalculation()函数。
但我怀疑的是我如何将所有Add,Sub,Mul和Div函数注册到ArithmeticOperations类中的委托,通过调用委托对象并将“Operation Success”返回到Form1类中的事件回调函数来调用所有函数?
答案 0 :(得分:3)
由于BasicCalculations
采用string
类型的单个参数,因此不能用于直接调用您的方法Add
,Subtract
等。
如果您希望PerformCalculations
通过多播调用每个方法,则需要一个等同于Action<int, int>
的类型的委托,例如:
class ArithmeticOperations
{
public delegate void BasicCalculations(string msg);
public event BasicCalculations StartCalculations;
private Action<int, int> calculations;
public ArithmeticOperations()
{
this.calculations += this.Add;
this.calculations += this.Sub;
}
public void PerformCalculations(int n1, int n2)
{
this.calculations.Invoke(n1, n2);
StartCalculations("Operation Success");
}
// ...
}
如果您希望您的个别算术方法使用字符串调用StartCalculations
事件,您可以让他们这样做:
void Add(int num1, int num2)
{
StartCalculations("Performing addition.");
}
在举起活动时,您应首先测试是否有订阅者(以避免NullReferenceException
)。 standard pattern是订阅任何处理程序,测试null
然后调用处理程序。如果有人在测试NullReferenceException
的事件后取消订阅,则会避免点击null
:
void Add(int num1, int num2)
{
var handler = this.StartCalculations;
if (handler != null)
{
handler("Performing addition.");
}
}
因为每个方法会重复很多代码,所以你可以将它重构为一个单独的方法:
void Add(int num1, int num2)
{
this.OnStartCalculation("Performing addition.");
}
void OnStartCalculation(string message)
{
var handler = this.StartCalculations;
if (handler != null)
{
handler(message);
}
}
答案 1 :(得分:3)
其中一个选项是创建私人活动
public delegate void BasicCalculations(string msg);
public delegate void DoMath(int na, int nb);
class ArithmeticOperations
{
public ArithmeticOperations()
{
StartMath += new DoMath(ArithmeticOperations_StartMath);
}
void ArithmeticOperations_StartMath(int na, int nb)
{
Add(na, nb);
Sub(na, nb);
Mul(na, nb);
Div(na,nb);
}
public event BasicCalculations StartCalculations;
private event DoMath StartMath;
public void PerformCalculations(int n1, int n2)
{
StartMath(n1, n2);
StartCalculations("Operation Success");
}
void Add(int num1, int num2)
{
Console.WriteLine("Performing addition.");
}
void Sub(int num1, int num2)
{
Console.WriteLine("Performing substraction.");
}
void Mul(int num1, int num2)
{
Console.WriteLine("Performing multiplication.");
}
void Div(int num1, int num2)
{
Console.WriteLine("Performing division.");
}
}