C#编程之委托与事件四(一)【转】
C#编程之委托与事件(一)
一. 委托
委托的本质
--在C#中,委托是一个特殊的类;
--在某种程度上,相当于C++的函数指针;
--在某种程度上,相当于接口(Interface);
委托的定义
--关键字:delegate
--public delegate void MyDelegate(string message);
注:在这里我们先了解一个概念,什么是函数签名?(在这里我不做过多解释,大家知道这个概念就行)。
使用委托
我们先来看看一个小的委托示例:
平时,如果说我们要设计一个做简单加减运算的方法,通常是怎么做的呢?看看下面代码:
class Program2

{3

/**//// <summary>4
/// 加法运算5
/// </summary>6
/// <param name="x">x</param>7
/// <param name="y">y</param>8
/// <returns></returns>9
private static int Add(int x, int y)
{
int result = x + y;
Console.WriteLine("x + y = {0}",result);
return result;
}

/**//// <summary>
/// 减法运算
/// </summary>
/// <param name="x">x</param>
/// <param name="y">y</param>
/// <returns></returns>
private static int Sub(int x, int y)
{
int result = x - y;
Console.WriteLine("x - y = {0}", result);
return result;
}
static void Main(string[] args)
{);
);
Console.Read();
}
}上面的代码只要是学过程序的人都能看懂,也写得出,不过我们怎么通过委托来处理+,-运算呢?请看下面定义:
namespace DelegateSample12


{3
//定义一委托4
public delegate int OperationDelegate(int x,int y);5
public class Operator6

{7
private int _x, _y;8
public Operator(int x, int y)9

{
this._x = x;
this._y = y;
}
public void Operate(OperationDelegate del)
{
del(_x, _y);
}
}
}上面定义一个返回int类型需要两个int参数的委托。Operator里提供了一个操作方法带有一个委托参数。那通过委托怎么来处理这个简单的运算呢?好,现在我们来修改我们之前定义的主方法,如下:
namespace DelegateSample12


{3
class Program4

{5

/**//// <summary>6
/// 加法运算7
/// </summary>8
/// <param name="x">x</param>9
/// <param name="y">y</param>
/// <returns></returns>
private static int Add(int x, int y)
{
int result = x + y;
Console.WriteLine("x + y = {0}",result);
return result;
}

/**//// <summary>
/// 减法运算
/// </summary>
/// <param name="x">x</param>
/// <param name="y">y</param>
/// <returns></returns>
private static int Sub(int x, int y)
{
int result = x - y;
Console.WriteLine("x - y = {0}", result);
return result;
}
static void Main(string[] args)
{
//声明一个委托对象
OperationDelegate del = null;
del += new OperationDelegate(Add);
del += new OperationDelegate(Sub);
);
op.Operate(del);
Console.ReadLine();
}
}
}
从上面的例子看,委托OperationDelegate代表了一组方法,他们的方法签名是:
--返回值:int; 参数:int ,int ;
只要符合该签名的方法,都可以赋给此委托:从上面不难看出,我要要创建一委托,则如下定义:
OperationDelegate del += new OperationDelegate(方法名);从上面可以看到(+=)这个运算符,那是不是也有(-=)这个运算符呢?这就涉及到另外一个概念了--委托链。
--委托链:实际上委托实例就是一个委托链,+=代表增加委托实例到委托链中,相反-=则代表去掉该委托实例。
OperationDelegate del = null;
del += new OperationDelegate(Add); //增加委托实例到委托链
del -= new OperationDelegate(Add); //去掉委托实例到委托的意义之一
--委托可以使得程序的复用程度提高;
--委托在一定程度上想当于接口;
例如:前面例子中的方法Operate(),由于接受的是一个委托类型;那么,我们可以对委托类型赋予不同的方法,来改变Operate()的性质。
我们在来看看另外一个示例:
--我们想输出一串数字,从0-100;
--对于输出的要求有三种;
-1、输出到控制台
-2、输出到窗体中的ListBox中;
-3、输出到文本文件中;
解决方案:
--使用委托和接口, 代码如下:
namespace DelegateSample22


{3
//定义一委托4
public delegate void ShowNumberDel(object[] items);5
public class ProcessNumber6

{7
private object[] items;8
public ProcessNumber(int max)9

{
items = new object[max];; i < max; ++i)

{
items[i] = i;
}
}
public void ProcessItems(ShowNumberDel show)
{
show(items);
}
}
}
在这里我们先把界面上的控件布局好并做好调用委托的准备工作,效果及代码如下:

代码如下:
private ProcessNumber pn = null;2
ShowNumberDel del = null;3

4
private void Form1_Load(object sender, EventArgs e)5


{);
7
}8

9
//到控制台
private void ShowInConsole(object[] items)

{
foreach (object item in items)
{
Console.WriteLine(item);
}
}
//到ListBox
private void ShowInListBox(object[] items)

{
listBox1.Items.Clear();
foreach (object item in items)
{
listBox1.Items.Add(item);
}
}
//到文本文件
private void ShowInFile(object[] items)

{
using (StreamWriter sw = new StreamWriter("Test.txt", true))
{
foreach (object item in items)
{
sw.WriteLine(item);
}
}
}使用委托:
private void button1_Click(object sender, EventArgs e)2


{3
pn.ProcessItems(new ShowNumberDel(ShowInConsole));4
}5

6
private void button2_Click(object sender, EventArgs e)7


{8
pn.ProcessItems(new ShowNumberDel(ShowInListBox));9
}
private void button3_Click(object sender, EventArgs e)

{
pn.ProcessItems(new ShowNumberDel(ShowInFile));
}
private void button4_Click(object sender, EventArgs e)

{
del += new ShowNumberDel(this.ShowInListBox);
del += new ShowNumberDel(this.ShowInFile);
pn.ProcessItems(del);
}完整的测试代码如下:

使用委托的完整测试代码1
using System;2
using System.Collections.Generic;3
using System.ComponentModel;4
using System.Data;5
using System.Drawing;6
using System.Text;7
using System.Windows.Forms;8
using System.IO;9

namespace DelegateSample2

{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private ProcessNumber pn = null;
ShowNumberDel del = null;
private void Form1_Load(object sender, EventArgs e)
{);
}
private void ShowInConsole(object[] items)
{
foreach (object item in items)
{
Console.WriteLine(item);
}
}
private void ShowInListBox(object[] items)
{
listBox1.Items.Clear();
foreach (object item in items)
{
listBox1.Items.Add(item);
}
}
private void ShowInFile(object[] items)
{
using (StreamWriter sw = new StreamWriter("Test.txt", true))
{
foreach (object item in items)
{
sw.WriteLine(item);
}
}
}
private void button1_Click(object sender, EventArgs e)
{
pn.ProcessItems(new ShowNumberDel(ShowInConsole));
}
private void button2_Click(object sender, EventArgs e)
{
pn.ProcessItems(new ShowNumberDel(ShowInListBox));
}
private void button3_Click(object sender, EventArgs e)
{
pn.ProcessItems(new ShowNumberDel(ShowInFile));
}
private void button4_Click(object sender, EventArgs e)
{
del += new ShowNumberDel(this.ShowInListBox);
del += new ShowNumberDel(this.ShowInFile);
pn.ProcessItems(del);
}
}
}委托的意义之二
--在C#中使用线程需要用到委托
- Thread thread = new Thread(new ThreadStart(target));
-target既为符号ThreadStart委托的方法名;
--函数回调
- 当我们定义了一个委托;
public delegate void MyDelegate(int source);
-对于异步调用来说,就有BeginInvoke()和EndInvoke()方法;
-del.BeginInvoke(source, new System.AsyncCallback(CallBack), "test");
-private void CallBack(IAsyncResult asyncResult)
{
int result = del.EndInvoke(asyncResult);
//......
}
这里需要理解的就是什么叫函数回调?这个话题留给大家讨论,在此不作详细解说。关于委托本文只是入门级的文章,要想更详细深入的学习委托请查看具体的书籍或资料,本文就简单介绍到这里。
C#编程之委托与事件四(一)【转】的更多相关文章
- C#编程之委托与事件四(二)【转】
C#编程之委托与事件(二) 我在上一篇文章(C#编程之委托与事件(一) )中通过示例结合的方法介绍了委托,在本文中,我同样以代码示例的方式来介绍C#里的事件机制. 二.事件 1.了解概 ...
- C#中委托和事件
目 录 将方法作为方法的参数 将方法绑定到委托 更好的封装性 限制类型能力 范例说明 Observer 设计模式简介 实现范例的Observer 设计模式 .NET 框架中的委托与事件 为什么委托定义 ...
- C#编程(四十二)----------委托和事件
委托和事件 委托是C#总比较重要的概念,学习C#爱这里最容易产生迷惑. 有些时候,犹豫我们在开发程序时对后续可能出现的要求及变化考虑不足而导致麻烦,这些新变化可能导致程序的重新编写,那能不能改变这种情 ...
- 详解C#泛型(二) 获取C#中方法的执行时间及其代码注入 详解C#泛型(一) 详解C#委托和事件(二) 详解C#特性和反射(四) 记一次.net core调用SOAP接口遇到的问题 C# WebRequest.Create 锚点“#”字符问题 根据内容来产生一个二维码
详解C#泛型(二) 一.自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型: void MyFunc<T>() //声明具有一个类型参数的泛型方法 { ...
- 3、二、c# 面向对像编程。类,结构、C# 数据类型(引用类型、值 类型、指针类型)、ref参数与out参数、方法的重载、静态类型与静态成员、继承与多态、委托与事件
一.类 定义类使用class关键字. <access specifier> class class_name { // member variables 成员变量 <access s ...
- 并发编程概述 委托(delegate) 事件(event) .net core 2.0 event bus 一个简单的基于内存事件总线实现 .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段 基于Ace Admin 的菜单栏实现 第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)
并发编程概述 前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ...
- C#高级编程 (第六版) 学习 第七章:委托和事件
第七章 委托和事件 回调(callback)函数是Windows编程的一个重要方面,实际上是方法调用的指针,也称为函数指针. .Net以委托的形式实现了函数指针的概念,.Net的委托是类型安全的. 委 ...
- .NET面试题系列[7] - 委托与事件
委托和事件 委托在C#中具有无比重要的地位. C#中的委托可以说俯拾即是,从LINQ中的lambda表达式到(包括但不限于)winform,wpf中的各种事件都有着委托的身影.C#中如果没有了事件,那 ...
- .NET基础拾遗(4)委托、事件、反射与特性
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...
随机推荐
- UVa 10806 & 费用流+意识流...
题意: 一张无向图,求两条没有重复的从S到T的路径. SOL: 网络流为什么屌呢..因为网络流的容量,流量,费用能对许许多多的问题进行相应的转化,然后它就非常的屌. 对于这道题呢,不是要没有重复吗?不 ...
- Coder-Strike 2014 - Round 1 D. Giving Awards
题目的意思是 老板给n个人发工资,x欠y的工资,the joy of person x from his brand new money reward will be much less, 老板想避免 ...
- ACM n-1位数
n-1位数 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描述 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的 ...
- ORA-01034错误:ORALCE NOT CONNECT
解决办法: 启动数据库 sqlplus '/as sysdba ' startup;
- tornado 学习笔记1 引言
从事软件开发这行业也快5年啦,其实从事的工作也不完全是软件开发,软件开发只是我工作中的一部分.其中包括课题研究.信息化方案设计.软件开发.信息系统监理.项目管理等工作,比较杂乱.开发的软件比较多,但是 ...
- FileUpload文件上传控件
1.FileUpload控件的主要功能是向指定目录上传文件.FileUpload控件不会自动上传控件,而需要设置相关的事件处理程序,然后在程序中实现文件上传. 2.FileUpload控件常见的属性 ...
- Node.js的DES加解密和MD5加密
最基本的就是经常用的md5加密算法 代码如下 var MD5=function (data) { var _encrymd5 = require('crypto').createHas ...
- Radar Installation
Radar Installation 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=86640#problem/C 题目: De ...
- (转)as3效率优化
1.改进算法无论对于那一种程序,好的算法总是非常重要的,而且能够极大地提高程序性能,所以任何性能的优化第一步就是从算法或者说程序逻辑的优化开始,检查自己的程序是否有多余的运算,是否在没有必要的时候做了 ...
- HighchartsJS创建点状带标识的图表实例
上一篇我发布的是关于 HighchartsJS创建环形带标识的图表实例, 从那篇文章就可以看出 HighchartsJS 确实是一款功能很强大的图表库.利用它,我们可以在项目中创建出我们所需要的图表来 ...