c#委托与代理

        .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; }
}

 

你可能感兴趣的:(c#委托与代理)