C#高级编程 (第六版) 学习 第七章:委托和事件

第七章 委托和事件

回调(callback)函数是Windows编程的一个重要方面,实际上是方法调用的指针,也称为函数指针。

.Net以委托的形式实现了函数指针的概念,.Net的委托是类型安全的。

  1. 委托

使用委托的时候,需要先声明,后实例化。

声明委托

delegate void MethodInvoker();

可以在委托前加public,private,protected。

 

实际上,定义委托是指定义一个新类,委托实现为派生自基类System.MulticastDelegate。

 

使用委托

private delegate string GetAString();

 

static void Main()

{

    int x = 10;

    GetAString firstMethod = new GetAString(x.ToString);

    Console.WriteLine("String is {0}", firstMethod());

    // Console.WriteLine("String is {0}", firstMethod.Invoke());

 

 

}

委托在语法上总是带有一个参数的构造函数,这个参数就是委托引用的方法

C#引入和委托推断:

GetAString firstMethod = x.ToString;

 

多播委托

包含多个方法调用的委托。调用委托的个数也与方法相同

delegate void DoubleOp(double value);

 

DoubleOp operations = MathOperations.MultiplyByTwo;

operations += MathOperations.Square;

operations(2.0);

会执行两个函数

也可使用-=

多播委托包含一个逐个调用的委托集合。如果通过委托调用的一个方法抛出了异常,整个迭代就会停止。解决方法:

DemoDelegate d1 = One;

d1 += Two;

 

Delegate[] delegates = d1.GetInvocationList();

foreach(DemoDelegate d in delegates)

{

    try

    {

    }

    catch(Exception)

    {

    }

}

 

匿名方法

delegate string DelegateTest(string val);

DelegateTest an1 = delegate(string param)

{

    statements;

};

 

lambada表达式

C#3.0引入,创建匿名函数

DelegateTest an1 = param =>

{

    statements;

    return "some string";

};

lambada表达式中,运算符=>左边列出了参数类型和个数

可以忽略类型,只写标识符,用括号括住,当标识符只有一个时,可以省略括号。

 

  1. 事件

例子

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Timers;

 

namespace Chapter_7

{

public delegate void MessageHandler(string messageText);

 

public class Connection

{

public event MessageHandler MessageArrived;

private Timer pollTimer;

private static Random random = new Random();

private uint count = 0;

 

public Connection()

{

pollTimer = new Timer(100);

pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);

}

 

public void Connect()

{

pollTimer.Start();

}

 

public void Disconnect()

{

pollTimer.Stop();

}

 

private void CheckForMessage(object source, ElapsedEventArgs e)

{

Console.WriteLine("Checking for new message.");

if ((random.Next(9) == 0) && (MessageArrived != null))

{

count++;

MessageArrived("Hello Mum!");

}

}

}

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Chapter_7

{

public class Display

{

public void DisplayMessage(string message)

{

Console.WriteLine("message arrived:{0}", message);

}

}

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Chapter_7

{

public delegate void DoubleOp(double value);

class Program

{

static void Main(string[] args)

{

 

Connection myConnection = new Connection();

Display myDisplay = new Display();

myConnection.MessageArrived += new MessageHandler(myDisplay.DisplayMessage);

myConnection.Connect();

Console.ReadKey();

}

}

}

第一行定义事件发布器

第二行定义事件订阅器

最后一行演示事件使用方法

参考:http://www.runoob.com/csharp/csharp-event.html

posted @ 2016-03-18 22:29  我是一个NLPer哦啦啦  阅读(295)  评论(0编辑  收藏  举报