C#委托

如果我们要把方法当做参数来传递的话,就要用到委托,委托可以赋值一个方法的引用,然后通过委托变量去调用这个方法,定义委托就是告诉编译器这个委托可以指向哪些类型的方法,然后创建委托实例

定义委托的语法如下:

delegate void Test(int x);

这句话的意思是定义一个名字为Test的委托,这个委托可以指向一个参数为一个int类型的,返回值为void的方法。

定义委托要定义方法的参数和返回值,使用关键字delegate定义。

这里再举几个例子:

delegate int GetMax(int a,int b);
delegate string Combine(string a,string b);

下面上几个完整的代码例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyDelegate
{
    class Program
    {
        private delegate string GetAString();//定义了一个委托GetAString

        static void Main(string[] args)
        {
            int x = 40;
            //使用委托创建实例
             GetAString a = new GetAString(x.ToString);//a指向了x中的tostring方法
             string s1 = a();//通过委托实例去调用x中的tostring方法(常用)
            GetAString b = x.ToString;//常用
            string s2 = b.Invoke();//通过invoke方法去调用x的tostring方法
            Console.WriteLine(s1);
            Console.WriteLine(s2);
            Console.ReadKey();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyDelegate
{
    class Program
    {
        delegate void PrintMes();
        static void Print(PrintMes print){
          print();//间接调用委托指向的方法
        }
       static void Test1(){
        Console.WriteLine("Test1");
       }
       static void Test2(){
        Console.WriteLine("Test2");
       }
        static void Main(string[] args)
        {
            PrintMes pm = Test1;
            Print(pm);//委托作为参数传递
            pm = Test2;//委托的实例就像变量一样可以更改所指向的引用
            Print(pm);
            Console.ReadKey();
        }
    }
}

系统内置的委托类型Action:

Action是系统内置的一个委托类型,它可以指向一个没有返回值,有参数的方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyDelegate
{
    class Program
    {
       static void Test1(){
        Console.WriteLine("Test1");
       }
       static void Test2(int a){
        Console.WriteLine("Test2"+a);
       }
        static void Main(string[] args)
        {
            Action a = Test1;//action是系统定义的无返回值的委托
            Action<int> b = Test2;//通过泛型可以指向一个没有返回值有参数的方法,参数个数为泛型的个数,用','隔开,且类型顺序与方法参数类型必须一致
            Console.ReadKey();
        }
    }
}

系统内置的委托类型Func:

Func是系统内置的一个委托类型,它可以指向一个有返回值,有参数的方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyDelegate
{
    class Program
    {
       static string Test1(){
        return "Test1";
       }
       static int GetRes(string a){
        Console.WriteLine(a);
        return 100;
       }
        static void Main(string[] args)
        {
            Func<string> a = Test1;//Func也是系统定义的委托,使用泛型来指定方法的返回值类型
            Func<string, int> b = GetRes;//Func可以指定多个泛型,最后一个泛型指定返回值类型,其它的为参数类型
            Console.ReadKey();
        }
    }
}

多播委托:

调用委托就会调用多个方法,就像广播一样,多播委托只能得到调用的最后一个方法的结果,一般我们把多播委托的返回类型声明为void

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyDelegate
{
    class Program
    {
       static void Test1(){
       Console.WriteLine("Test1");
       }
       static void Test2(){
       Console.WriteLine("Test2");
       }
        static void Main(string[] args)
        {
            Action a = Test1;
            a += Test2;//使用+号将方法串联起来
            a();
            a -= Test1;//将Test1方法移除
            a();//如果委托为空,调用的时候就会报错,所有一般都会先判断空
            Delegate[] delegates = a.GetInvocationList();//得到委托所调用的方法集合
            foreach(Delegate d in delegates){
               d.DynamicInvoke();//单独调用方法,如果方法有参数,直接写在DynamicInvoke()括号里
            }
        }
    }
}

匿名方法:

匿名方法就是没有名字的方法,所以调用的时候只能赋值给委托去调用了

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyDelegate
{
    class Program
    { 
        static void Main(string[] args)
        {
         //匿名方法
           Func<int,int,int> a = delegate(int arg1,int arg2)
           {
              return agr1+arg2;
           }; 
        }
    }
}

Lambda表达式:

lambda表达式是用来代替匿名方法的,所以一个lambda表达式也是定义了一个方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyDelegate
{
    class Program
    { 
        static void Main(string[] args)
        {
        //lambda表达式可以不用delegate关键字,和参数变量类型
         Func<int,int,int> plus = (arg1,arg2)=>
         {
           return arg1+arg2;
         };

         Func<int,int> test = a=>a+1;//lambda表达式如果参数为一个则可以去掉括号,当函数体只有一句话时可以不加上大括号和return语句,编译器会自动添加return语句
        }
    }
}

事件:

在委托前面加上event后便成了事件,事件的基本用法与委托基本一样,区别在于,事件不能在类外触发

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyDelegate
{
    class Program
    { 
    public delegate void TestDelegate();
    public event TestDelegate testDelegate;//声明事件
        static void Main(string[] args)
        {

        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值