您的位置:首页 > 编程语言 > C#

C#委托

2017-03-30 18:48 99 查看

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

定义委托的语法如下:

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");

bc81
}
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)
{

}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C# 委托