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

C#编程入门_委托、事件、Lambda表达式_20

2017-07-19 07:10 435 查看
21篇C#博客的配套源码

声明委托

委托声明决定了可由该委托引用的方法。委托可指向一个与其具有相同签名的方法。

委托的声明和方法的声明时一样,只不过多了一个delegate修饰符

委托不是方法,而是一种类型
委托是引用类型

如下两种委托限定了回调方法的类型
public delegate int YyDelegate();
public delegate int MyDelegate (string s);


实例化委托

声明委托后,我们可以通过new关键字来创建委托。委托的构造方法中需要填入的是方法的名 ,注意不带有参数:

例如:

delegate void MyDelegate();

MyDelegate mydel = new MyDelegate(Test);

需要回调的方法:

void Test()

{

Console.WriteLine(“YY真帅”);

}

我们还可以直接赋值:

MyDelegate del = Test;

多播委托

委托对象可使用 “+” 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。”-” 运算符可用于从合并的委托中移除组件委托。

使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表。这被称为委托的 多播(multicasting),也叫组播

在生活办公中使用的打印机就是一个多播的一个实例:

例如张三需要打印一个文件,打印耗时5分钟,李四也需要打印一个文件,那么李四只需要向打印机发出打印文件的命令即可,在打印张三的文件结束后,再打印李四的文件。如果李四反悔了,就可以撤销刚才的操作。

事件

事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些出现,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。事件是用于进程间通信。

声明事件

在类的内部声明事件,首先必须声明该事件的委托类型。

public delegate void BoilerLogHandler(string status);

然后,声明事件本身,使用 event 关键字:

// 基于上面的委托定义事件

public event BoilerLogHandler BoilerEventLog;

使用事件实现观察者模式

发布者

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

namespace 事件案例1
{

delegate void MyDelegate(string str);
class Promulgator
{
public event MyDelegate handler;

public void AddEvent(MyDelegate func)
{
handler += func;
}

public void SubEvent(MyDelegate func)
{
handler -= func;
}

public void ExeEvent(string str)
{
if (handler!=null)
{
handler.Invoke(str);
}
}
}
}


订阅者

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

namespace 事件案例1
{
class Subscriber
{
private string name;

public Subscriber(string name)
{
this.Name = name;
}

public string Name
{
get
{
return name;
}

set
{
name = value;
}
}

public void Notice(string str)
{
Console.WriteLine("{0},{1}",Name,str);
}
}
}


Program

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

namespace 事件案例1
{
class Program
{
static void Main(string[] args)
{
Promulgator p = new Promulgator();
Subscriber xiaoming = new Subscriber("小明");
p.AddEvent(xiaoming.Notice);
Subscriber wangyao = new Subscriber("王垚");
p.AddEvent(wangyao.Notice);
Subscriber yadong = new Subscriber("亚东");
p.AddEvent(yadong.Notice);
p.ExeEvent("老板来了,各就各位");
}
}
}


Lambda表达式

在Framework 2.0 以前,声明委托的唯一方法是通过方法命名,从Framework 2.0 起,系统开始支持匿名方法。

通过匿名方法,可以直接把一段代码绑定给事件,因此减少了实例化委托所需的编码系统开销。

而在 Framework 3.0 开始,Lambda 表达式开始逐渐取代了匿名方法,作为编写内联代码的首选方式。总体来说,Lambda 表达式的作用是为了使用更简单的方式来编写匿名方法,彻底简化委托的使用方式。

Action

常用泛型委托:Action

此委托由系统提供 无需声明

Action 支持0~16个参数,可以按需求任意使用。

public delegate void Action()

public delegate void Action< T1>(T1 obj1)

public delegate void Action< T1,T2> (T1 obj1, T2 obj2)

public delegate void Action< T1,T2,T3> (T1 obj1, T2 obj2,T3 obj3)

…………

public delegate void Action< T1,T2,T3,……,T16> (T1 obj1, T2 obj2,T3 obj3,……,T16 obj16)

static void Main(string[] args)
{
int x = 1000;
Action action = () => x = x + 500;
action.Invoke();

Console.WriteLine("Result is : " + x);
}

static void Main(string[] args)
{
Action<int> action = (x) =>
{
x = x + 500;
Console.WriteLine("Result is : " + x);
};
action.Invoke(1000);

}


Func

委托 Func 与 Action 相似,同样支持 0~16 个参数,不同之处在于Func 必须具有返回值

public delegate TResult Func()

public delegate TResult Func

static void Main(string[] args)
{
Func<double, bool, double> func = Account;
double result=func(1000, true);
Console.WriteLine("Result is : "+result);
}
static double Account(double a,bool condition)
{
if (condition)
return a * 1.5;
else
return a * 2;
}

static void Main(string[] args)
{
Func<double, bool, double> func = (a,condition) =>
{
if (condition)
{
return a * 1.5;
}
else
{
return a * 2;
}
};
double result=func(1000, true);
Console.WriteLine("Result is : "+result);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: