Delegates, events, lambda expres

2019-11-01  本文已影响0人  柒轩轩轩轩

Delegates 委托

委托是一个对象,它知道如何调用一个方法

委托类型和委托实例

delegate int Transformer (int x); //define argument type is int, and return type is int 委托类型
static int Square (int x) {return x *x} // 上面的委托类型可以调用这个方法,因为类型一致
public class Program
{
  delegate int Transformer(int x);
  static int Square(int x) => x * x;
  static void Main ()
  {
    Transformer t = Square; //Create delegate instance
    int result = t(3); //Invoke delegate 
    Console.WriteLine(result);
  }
static int Square (int x) => x *x;
}

委托实例

编写插件式的方法

public delegate int Transformer(int x);
class Util
{
  public static void Transform(int[] values, Transformer t)
  {
    for (int i = 0; i < values.Length; i ++)
      {
        values[i] = t(values[i]);
      }
  }
}

public class Program 
{
  static int Square(int x) => x*x;

  static void Main()
  {
    int[] values = {1,2,3};
    Util.Transform(values, Square);
    foreach (int i in values)
    {
      Console.WriteLine($"{i}");
    }
  }
}

多播委托

所有的委托实例都具有多播的能力,一个委托实例可以引用一组目标方法

实例方法目标和静态方法目标

public delegate void ProgressReporter (int percentComplete)
class X
{
  public void InstanceProgress (int percentComplete) 
  => Console.WriteLine(percentComplete);
}
class Program
{
  static void Main()
  {
    X x = new X();
    ProgressReporter p = x.InstanceProgress;
    p(99); //99
    Console.WriteLine(p.Target == x); //True  
    Console.WriteLine(p.Method); //Void InstanceProgress(int32);
  }
}

泛型委托类型

public delegate T Transformer<T>(T arg);

public class Util
{
  public static void Transform<T>(T[] values, Transformer<T> t)
  {
    for (int i = 0; i < values.Length; i++)
    values[i] = t(values[i]);
  }
}
class Test 
{
  static void Main()
  {
    int [] values = {1,2,3};
    Util.Transform(values, Square);
    foreach (int i in values)
        Console.Write(i + " "); //1 4 9
  }
  static int Square(int x) => x* x;
}

Func 和 Action委托

使用泛型委托,就可以写出这样一组委托类型,他们可调用的方法可以拥有任意的返回类型和任意(合理)数量的参数

delegate TResult Func <out TResult> ();
delegate TResult Func <in T, out TResult> (t arg);
delegate TResult Func <in T1, in T2, out TResult> (T1 arg1, T2 args)

delegate void Action ();
delegate void Action <in T> (T arg);
delegate void Action <in T1, in T2> (T1 arg1, T2 arg2);
public class Util
{
  public static void Transform<T>(T[] values, Func<T,T> t)
  {
    for (int i = 0; i < values.Length; i++)
    values[i] = t(values[i]);
  }
}

委托 vs 接口

委托的兼容性 - 委托类型

委托类型之间互不相容,即使方法签名一样:

delegate void D1();
delegate void D2();

D1 d1 = Method1;
D2 d2 = d1; //Compile-time error

委托的兼容性 - 委托实例

如果委托实例拥有相同的方法目标,那么委托实例就认为是相等的

delegate void D();
...
D d1 = Method1;
D d2 = Method1;
Console.WriteLine(d1 == d2); //True

委托的兼容性 - 参数

delegate void StringAction (string s);
class Test
{
  static void Main()
  {
  StringAction sa = new StringAction(ActOnObject);
  sa("hello");
  }
  static void ActOnObject (object o) => Console.WriteLine(o); //hello
}

委托的兼容性- 返回类型

上一篇下一篇

猜你喜欢

热点阅读