• .NET基础学习(委托)


    最近学习C#基础,特此做笔记,请不要

    委托和类一样,是一种用户自定义的类型。类表示的是数据的集合,而委托保存的是一个或多个方法。

    1、申明委托类型

    delegate void MyDel(int x)

    上面代码申明了MyDel类型的委托,指明了这种类型的委托只会接受不返回值并且只有单个int参数的方法。

    2、创建委托对象

    委托是引用类型,因此有引用和对象。在委托类型申明之后,我们可以申明变量并创建类型的对象。

    class del
    {
    public del()
    {
    MyDel delVar = new MyDel(b.GetB);//实例方法,创建委托并保存引用
    }
    delegate void MyDel(int x);//申明委托类型
    B b = new B();
    MyDel dVar = new MyDel(B.GetA);//实例方法,创建委托并保存引用
    }

    public class B
    {
    static public void GetA(int y)
    {
    Console.WriteLine("静态方法!输出值为:" + y);
    }
    public void GetB(int z)
    {
    Console.WriteLine("成员方法!输出值为:" + z);
    }
    }

    上面代码创建了2个委托对象,一个具有实例方法,一个具有静态方法。b为类B的对象,它有一个叫做GetB实例方法,该方法接收一个int类型的参数,不返回值;B类有一个GetA静态方法,该方法具有与MyDel委托想匹配的返回类型和签名。

    3、赋值托管

    MyDel delVar;
    delVar=b.GetB;//创建并给委托对象赋值
    ……
    delVar=B.GetA;//创建并给新的委托对象赋值

    由于委托是引用类型,我们可以通过给它赋值来改变包含在委托变量中的引用,旧的委托对象会被垃圾回收器回收。

    4、组合委托

    MyDel delA=A.GetA;
    MyDel delB=B.GetB;
    MyDel delC=delA+delB;//组合调用列表

    尽管术语组合委托让我们觉得好像操作委托被修改了,其实它们并没有被修改。事实上,委托是恒定的,委托被创建后不会再被改变。

    5、为委托增加方法

    MyDel delVar=A.GetA;//创建并初始化
    delVar+=B.GetB;//增加方法
    delVar+=C.GetC;//增加方法

    委托是不可变的,所以委托的调用列表增加3个方法后的结果其实是变量指向一个全新的委托。

    6、从委托移除方法

    delVar-=C.GetC;//从委托移除方法

    与为委托增加方法一样,其实是创建了一个新的委托,新委托是就委托的一个副本,只是没有了已移除方法的引用。

    1.如果在调用列表中的方法有多个实例,-=运算符将从列表最后开始搜索,并且移除第一个与方法匹配的实例。

    2.试图删除委托中不存在的方法没有结果。

    3.视图调用空委托会抛出异常。

    4.如果调用列表为空,则委托是null。

    7、调用委托

     delegate void printFunction();//定义一个没有返回值和参数的委托类型
    class Program
    {
    static void Main(string[] args)
    {
    Test t = new Test();//创建测试类实例
    printFunction pf;//创建一个空委托
    pf = t.Print1;//实例化并初始化该委托
    //给委托增加3个另外的方法
    pf += Test.Print2;
    pf += t.Print1;
    pf += Test.Print2;
    if (null != pf)//确认委托有方法
    pf();//调用委托
    else
    Console.WriteLine("Delegage is empty");
    }
    }
    class Test
    {
    public void Print1()
    { Console.WriteLine("Print1--instance"); }
    static public void Print2()
    { Console.WriteLine("Print2--static"); }
    }

    Test类定义了两个打印函数,一个是实例成员函数一个是静态成员函数,在调用委托之前,检测是否为null,程序打印结果如下图

    8、调用带返回值的委托

    如果委托有返回值并且在调用列表中有一个以上的方法,调用列表中最后一个方法返回的值就是委托调用返回的值,调用列表中所有其他方法的返回值都会被忽略。

     delegate int Add();//定义一个有回值和无参数的委托类型
    class Program
    {
    static void Main(string[] args)
    {
    Test t = new Test();//创建测试类实例
    Add add = t.Add1;
    add += t.Add2;
    add += t.Add1;
    Console.WriteLine(add());
    }
    }
    class Test
    {
    int val = 5;
    public int Add1()
    { val += 2; return val; }
    public int Add2()
    { val += 3; return val; }
    }

    add();->Add1();返回值7被忽略->Add2();返回值10被忽略->Add1();使用,返回值为12

    上面代码申明了返回int值的委托,然后调用委托打印出值,运行结果如图所示:

    9、调用带引用参数的委托

    如果委托有引用参数,参数值会根据调用列表的的一个或者多个方法的返回值而改变。

    在调用委托列表下的方法时,参数的新值(不是初始值)会传给下一个方法。

    delegate void MyDel(ref int x);//定义一个有回值和无参数的委托类型
    class Program
    {
    public void Add1(ref int x) { x += 2; }
    public void Add2(ref int x) { x += 3; }
    static void Main(string[] args)
    {
    Program p=new Program();
    MyDel mDel = p.Add1;
    mDel += p.Add2;
    mDel += p.Add1;
    int x = 5;
    mDel(ref x);
    Console.WriteLine(x);
    }
    }

    mDel();->Add1(X=5);引用x的初始值->Add2(X=7);引用x新的输入值->Add1(x=10);引用x的新的输入值

    打印如图所示:

    10、匿名方法

    匿名方法:是子初始化委托时内联申明的方法。

    delegate int MyDel(int x);//定义一个有回值和无参数的委托类型
    class Program
    {
    static void Main(string[] args)
    {
    MyDel del = delegate(int x)
    {
    return x += 20;
    };
    Console.WriteLine(del(123));
    Console.WriteLine(del(1234));
    }
    }

    如果匿名方法申明的参数列表中包含了params参数,那么parmas关键字就会被匿名方法的参数列表忽略

    delegate int MyDel(int x,params int[] y);//定义一个有回值和参数的委托类型
    class Program
    {
    static void Main(string[] args)
    {
    MyDel del = delegate(int x,int[] y)
    {
    return x + y.Length;
    };
    Console.WriteLine(del(1,1,2,3,4));
    }
    }

    打印结果如下图示:

    11、Lambda表达式

    在匿名方法的语法中,delegate关键字是有点多余的,因为编译器已经知道我们将在方法赋值给委托,下面把匿名方法转换为lambda表达式

     delegate int MyDel(int x);
    class Program
    {
    static void Main(string[] args)
    {
    MyDel del = delegate(int x) { return x + 1; };//匿名函数
    MyDel del1 = (int x) => { return x + 1; };//lambad表达式
    MyDel del2 = (x) => { return x + 1; };
    MyDel del3 = x => { return x + 1; };
    MyDel del4 = x => x + 1;
    Console.WriteLine(del(12));
    Console.WriteLine(del1(12));
    Console.WriteLine(del2(12));
    Console.WriteLine(del3(12));
    Console.WriteLine(del4(12));
    }
    }

    版权所有,转载请注明出处!

    一切伟大的行动和思想,都有一个微不足道的开始。微不足道的我,正在吸取知识的土壤,希望能取得成功!不嫌弃我微不足道的,愿交天下好友!

  • 相关阅读:
    怎么使用git来管理项目版本?
    《我的四季》 张浩
    [代码片段]读取BMP文件(二)
    [代码片段]读取BMP文件
    《构建之法》阅读笔记02
    二维数组
    学习进度二
    《构建之法》阅读笔记01
    数组
    软件工程第一周开课博客
  • 原文地址:https://www.cnblogs.com/cmsdn/p/2306669.html
Copyright © 2020-2023  润新知