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

C# 委托知识总结

2013-07-05 16:53 302 查看
         代码下载地址:

http://dl5.csdn.net/fd.php?i=674857074216254&s=9e5faa674c1f7262b25025b53d3ec5e2
在程序过程中,当程序正在处理某个事件的时候,我需要另外的程序代码去辅助处理一些事情,于是委托另一个程序模块去处理,而委托就可以达到这种目的,我可以利用委托通知另外的程序模块,该去调用哪个函数方法。委托其实就起到了这样一个作用,将函数签名传递到了另一个函数中。或许这样讲还是有些模糊,看看后面的具体实例。

3.委托的三种形式

(1).推断
(2) 匿名函数
(3)多播委托

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

namespace Delegate
{
public delegate void MyDelegate(string name);

///
/// 热水器
///
public class Heater
{
public  MyDelegate Ondrinking;
private void RasieBoiledEvent()
{
if (Ondrinking == null)
{
Console.WriteLine("加热完成处理订阅事件为空");
}
else
{
Ondrinking("ivan");
}
}
private Thread heatThread;
public void Begin()
{
heatTime = 5;
heatThread = new Thread(new ThreadStart(Heat));
heatThread.Start();
Console.WriteLine("水正在煮", heatTime);

}
private int heatTime;
private void Heat()
{
while (true)
{
Console.WriteLine("还需{0}秒", heatTime);

if (heatTime == 0)
{
RasieBoiledEvent();
return;
}
heatTime--;
Thread.Sleep(1000);
}
}
}
}


3.委托的三种形式

(1).推断

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

namespace Delegate
{
class Program
{
static void Main(string[] args)
{
var test = new Heater();
test.Ondrinking = TestOndrinking;
test.Begin();
Console.ReadKey();
}

static void TestOndrinking(string name)
{
Console.WriteLine(string.Format("{0},水可以喝了!",name));
}
}
}


在委托定义的例子中我们看到委托的使用方法是在委托实例化的时候指定的[new DelegateName(FunctionName)],这里可能表述不是太但是代码应该看得白了。 而委托的推断,并没有new 委托这个步骤,而是直接将Function 指定给委托。

(2).匿名函数

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

namespace Delegate
{
class Program
{
static void Main(string[] args)
{
var test = new Heater();
test.Ondrinking = delegate(string name)
{
Console.WriteLine(string.Format("{0},水可以喝了!", name));
};
test.Begin();
Console.ReadKey();
}
}
}


至于匿名委托,给人的感觉更为直接了,都不用显示的指定方法名,因为根本没有方法,而是指定的匿名方法。匿名方法在.NET 中提高了 

代码的可读性和优雅性。对于更多操作较少的方法直接写为匿名函数,这样会大大提高代码的可读性。这里有两个值得注意的地方: 第一,不能使用

跳转语句跳转到该匿名方法外,第二 不能使用ref,out修饰的参数

(3).多播委托

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

namespace Delegate
{
class Program
{
static void Main(string[] args)
{
var test = new Heater();
MyDelegate mydele1 = TestOndrinking;
MyDelegate mydele2 = TestOndrinking1;
test.Ondrinking = mydele1 + mydele2;
test.Begin();
Console.ReadKey();
}
static void TestOndrinking(string name)
{
Console.WriteLine(string.Format("{0},水可以喝了!",name));
}

static void TestOndrinking1(string name)
{
Console.WriteLine(string.Format("{0},图纸拿来了!", name));
}
}
}


  还是上面的那个实例,我不尽想让女朋友去给我掉杯水,还让她帮我将程序设计图稿拿过来。这个时候做的就不是一件事了,而是多件。

程序中也有很多这种情况,于是我们需要多播委托,在一个委托上指定多个执行方法,这是在程序中可以行的。上面提到了,委托直接继承于

System.MulticastDelegate,正是因为这个类可以实现多播委托。如果调用多播委托,就可以按顺序连续调用多个方法。为此,委托的签名就必须返回void;否则,就只能得到委托调用的最后一个方法的结果。所以在上面的这段代码中是得不到结果的

 

4.事件

使用C#编程,无论是WinForm,WebForm 给人很难忘得就是它的控件,而他们的控件库使用方式都是使用使用事件驱动模式,而事件驱动模式却少不了委托。话不多说,看代码能够更清好的理解事件和委托之间的联系. 

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

namespace Delegate
{

public delegate void MyDelegate(string name);

///
/// 热水器
///
public class Heater
{
public event MyDelegate Ondrinking;
private void RasieEvent()
{
if (Ondrinking == null)
{
Console.WriteLine("加热完成处理订阅事件为空");
}
else
{
Ondrinking("ivan");
}
}
private Thread heatThread;
public void Begin()
{
heatTime = 5;
heatThread = new Thread(new ThreadStart(Heat));
heatThread.Start();
Console.WriteLine("水正在煮", heatTime);

}
private int heatTime;
private void Heat()
{
while (true)
{
Console.WriteLine("还需{0}秒", heatTime);

if (heatTime == 0)
{
RasieEvent();
return;
}
heatTime--;
Thread.Sleep(1000);

}
}
}
}

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

namespace Delegate
{
class Program
{
static void Main(string[] args)
{
var test = new Heater();
test.Ondrinking += TestOndrinking;
test.Ondrinking += TestOndrinking1;
test.Begin();
Console.ReadKey();
}

static void TestOndrinking(string name)
{
Console.WriteLine(string.Format("{0},水可以喝了!",name));
}

static void TestOndrinking1(string name)
{
Console.WriteLine(string.Format("{0},图纸拿来了!", name));
}

}
}


代码下载地址:
http://dl5.csdn.net/fd.php?i=674857074216254&s=9e5faa674c1f7262b25025b53d3ec5e2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: