.NET中的每个事件,无论是系统的还是自己定义的,都基于.NET委托。 委托是.NET包含的五种类型之一-类、结构、接口,枚举和委托。
创建事件后,它指向容器(类或结构)中的方法(实例或静态)。 对于事件,它指向事件处理程序方法。它确切地定义了它可以指向的方法的种类,包括参数的数量和类型以及返回类型。
下面是一个简单的委托的定义。 可以在名称空间级别声明它,这意味着它不需要嵌套在类中。 下面的委托只能指向一个接受两个整数参数并返回一个整数的方法。 参数“ a”和“ b”从不直接使用,但需要使用它们来定义委托。
public delegate int dgPointer(int a, int b);
可以创建指向方法的委托实例。 然后,每次您调用委托时,它都会为您调用方法。 如果该方法返回一个值,则委托将为您返回它。 这是一个完整的简单示例。
public delegate int dgPointer(int a, int b);
class Program
{
static void Main()
{
Adder a = new Adder();
dgPointer pAdder = new dgPointer(a.Add);
int iAnswer = pAdder(4, 3);
Console.WriteLine("iAnswer = {0}", iAnswer);
// Returns “iAnswer = 7”
}
}
public class Adder
{
public int Add(int x, int y)
{ return x + y; }
}
.NET中的所有C#事件均基于委托。
无论何时要使用事件,都必须定义该事件。
除非至少一个对象正在监听(订阅)该事件,否则切勿引发(发布)事件。 换句话说,事件不能等于null。
Microsoft最佳实践:应定义所有事件,均以单词“ On”开头。
仅当有任何代码订阅该代码时,此代码才会引发C#事件。 让我们删除简单的委托并让其订阅事件来修改代码。
public class Adder
{
public delegate void dgEventRaiser();
public event dgEventRaiser OnMultipleOfFiveReached;
public int Add(int x, int y)
{
int iSum = x + y;
if ((iSum % 5 == 0) && (OnMultipleOfFiveReached != null))
{ OnMultipleOfFiveReached(); }
return iSum;
}
}
class Program
{
static void Main()
{
Adder a = new Adder();
a.OnMultipleOfFiveReached += new Adder.dgEventRaiser(a_MultipleOfFiveReached);
int iAnswer = a.Add(4, 3);
Console.WriteLine("iAnswer = {0}", iAnswer);
iAnswer = a.Add(4, 6);
Console.WriteLine("iAnswer = {0}", iAnswer);
Console.ReadKey();
}
static void a_MultipleOfFiveReached()
{
Console.WriteLine("Multiple of five reached!");
}
}
上面的长代码行可以缩短为以下代码段,效果相同。
a.OnMultipleOfFiveReached += a_MultipleOfFiveReached;
下面是系统自带的委托:
public delegate void EventHandler(object sender, EventArgs e);
public delegate void EventHandler(object sender, TEventArgs e);
第一个委托仅用于引发通知,该事件表示发生了某些事件。 第二个委托使您可以将一个或多个值返回到事件处理程序方法。 它要求您创建一个从EventArgs类派生的类的实例。
要修改我们的代码以使用第一个内置委托,我们可以删除委托并更改C#事件以使用EventHandler委托。 引发事件时,必须遵循委托定义,并传入所需的参数值。 请注意,我们如何为第一个参数(发送者)传递当前的adder实例,并且由于我们没有传递任何事件参数,因此将EventArgs.Empty用作“ e”。
我们还必须更改事件处理程序方法,以使用(对象发送者,EventArgs e)委托的模式。
class Program
{
static void Main()
{
Adder a = new Adder();
a.OnMultipleOfFiveReached += a_MultipleOfFiveReached;
int iAnswer = a.Add(4, 3);
Console.WriteLine("iAnswer = {0}", iAnswer);
iAnswer = a.Add(4, 6);
Console.WriteLine("iAnswer = {0}", iAnswer);
Console.ReadKey();
}
static void a_MultipleOfFiveReached(object sender, EventArgs e)
{
Console.WriteLine("Multiple of five reached!");
}
}
public class Adder
{
public event EventHandler OnMultipleOfFiveReached;
public int Add(int x, int y)
{
int iSum = x + y;
if ((iSum % 5 == 0) && (OnMultipleOfFiveReached != null))
{ OnMultipleOfFiveReached(this, EventArgs.Empty); }
return iSum;
}
}
为了使用另一个委托并传递回事件处理方法,我们首先需要定义一个名为MultipleOfFiveEventArgs的自定义类,以将自定义值(如Total)传递回去。 它必须继承自EventArgs类。
然后,我们将需要定义事件以使用另一个通用委托,其中包括自定义EventArgs类型MultipleOfFiveEventArgs。 我们还必须改变活动的方式。 最后,我们更改事件处理程序方法以匹配委托。 这是完整的代码:
class Program
{
static void Main()
{
Adder a = new Adder();
a.OnMultipleOfFiveReached += a_MultipleOfFiveReached;
int iAnswer = a.Add(4, 3);
Console.WriteLine("iAnswer = {0}", iAnswer);
iAnswer = a.Add(4, 6);
Console.WriteLine("iAnswer = {0}", iAnswer);
Console.ReadKey();
}
static void a_MultipleOfFiveReached(object sender, MultipleOfFiveEventArgs e)
{
Console.WriteLine("Multiple of five reached: ", e.Total);
}
}
public class Adder
{
public event EventHandler OnMultipleOfFiveReached;
public int Add(int x, int y)
{
int iSum = x + y;
if ((iSum % 5 == 0) && (OnMultipleOfFiveReached != null))
{ OnMultipleOfFiveReached(this, new MultipleOfFiveEventArgs(iSum)); }
return iSum;
}
}
public class MultipleOfFiveEventArgs : EventArgs
{
public MultipleOfFiveEventArgs(int iTotal)
{ Total = iTotal; }
public int Total { get; set; }
}