委托

委托

委托类似于c/c++中的函数指针。委托是一个对象,并且是类型安全的,避免了函数指针的不安全性,一个委托类型的变量可以引用一个或多个方法,这些方法有委托存放于一个调用列表中,当调用一个委托类型的变量,即相当于一次调用它的调用列表中的方法(包括实例方法和静态方法)。

public delegate void PrintDelegate(string content);

被引用方法的签名要和委托一致,比如方法参数的个数和类型,方法的返回值要和委托一致。
委托和类一样都是引用类型,每一个委托都默认继承自System.MulticastDelegate类,而后者是抽象类,他又继承自System.Delegate类。

使用示例

public delegate void PrintDelegate1();
public delegate int PrintDelegate2();
public delegate int PrintDelegate3(string content, bool isA4Paper);

public class Sample
{
    public static void Main(){
        //委托可以通过方法赋值进行初始化
        //PrintDelegate1 pd1 = test1;
        PrintDelegate1 pd1 = delegate
        {
            Console.WriteLine("Printing...");
        };
        //委托可以通过new来进行初始化委托
        //PrintDelegate1 pd1 = new PrintDelegate1(test1);
        //针对相同签名方法,可增加删除方法列表
        pd1 += test1;
        pd1 += test2;
        pd1 -= test1;

        //同类的委托之间也可以使用+/-进行组合
        PrintDelegate1 pd4 = test2;
        PrintDelegate1 pd5 = pd4 + pd1;
        
        PrintDelegate2 pd2 = delegate
        {
            Console.WriteLine("Printing...");
            return 1;
        };
        PrintDelegate3 pd3 = delegate(string content, bool isA4Paper)
        {
            Console.WriteLine("Printing...");
            return 2;
        };

        
        pd1();
        pd2();
        pd3();
    }

    public void test1(){}
    public void test2(){}
}

委托中的协变与逆变

  • 协变:委托方法中的返回值类型直接或间接地继承自委托签名的返回值类型
  • 逆变:委托签名中的参数类型继承自委托方法的参数类型

匿名方法

匿名方法在本质上是一个传递给委托的代码块,最大优势在于其减少了系统开销,方法仅在委托使用时才定义。
匿名方法的使用规则:

  • 匿名方法中不能使用跳转语句,制止匿名方法的外部,反之亦然,匿名方法外部的跳转语句也不能跳到另一方法的内部
  • 在匿名方法内部不能访问不安全的代码,另外也不能访问在匿名放到外部定义的和参数,但可以使用在匿名发往外部定义的其他变量

Lamda表达式

Lamda表达式和匿名方法基本相同,只是语法不同。(param) => expr param是一个输入参数列表,expr是一个表达式或者一系列语句。
具有以下特性:

  • 一个具有唯一的显式类型参数的表达式中,圆括号可以从参数列表中删除,(param) => expr 可以写成 param => expr;
  • 当输入参数不唯一时,括号则不能省略
  • 输入参数列表中的各参数可以显式指定类型,也可以活力掉参数类型,具体类型通过类型推断机制判断
  • expr可以只包含一个计算表达式,也可以包含一系列语句,只是语句需要包括在大括号内
public delegate string PrintDelegate(string content);

public class Sample
{
    public static void Main()
    {
        PrintDelegate pd = (str) => str += “xxx”;
        string result = pd(“something”);
        Console.WriteLine(result);
    }
}
posted @ 2019-06-04 08:27  Allen2015  阅读(276)  评论(0编辑  收藏  举报