C#委托初探
委托是一种定义方法签名的类型,可以与具有兼容签名的任何方法关联。您可以通过委托调用其中已添加的方法列表。委托用于将方法作为参数传递给其他方法。事件处理程序就是通过委托调用的方法。您可以创建一个自定义方法,当发生特定事件时某个类(例如 Windows 控件)就可以调用您的方法。button的单击事件发生后,通过委托这个管道找到用户添加的处理方法,从而执行方法;不必像之前win32程序那样循环等待某个事件消息。
先直接添端代码进来,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Test_Delegate
{
//定义一个委托,对应方法签名为 int Fun(int , int )
//编译器会自动生成一个委托类 dgOP,在此相当于声明一个类对象,稍后使用时new实例化
//继承链如:Delegate:MulticastDelegate:Delegate:ICloneable,ISerializable
public delegate int dgOP(int x, int y);
//生成的类形如
//sealed class dgOP : System.MulticastDelegate
//{
// //构造函数,原理不清楚 !!
// public dgOP(object target,unit functionAddr);
// //成员函数,可在外调用
// public virtual int Invoke(int x, int y);
// public virtual IAsyncResult BeginInvoke(int x, int y
// , AsyncCallback callback, object @object);
// public virtual int EndInvoke(IAsyncResult result);
//} public class SimpleMath
{
/***********静态方法*******************/
public static int Add(int x, int y)
{
Console.WriteLine("add");
return x + y;
}
public static int Square(int x)
{
return x * x;
}
/***********动态方法*******************/ public int Sub(int x, int y)
{
Console.WriteLine("sub");
return x - y;
}
} class Program
{
static dgOP dg;
static void Main(string[] args)
{
//静态方法
//实例化上文中定义的(编译器自动生成的)委托类,并指定方法
//+=内部隐式调用dgOP.Combine
//Del(new dgOP(SimpleMath.Add));
dg = dgOP.Combine(new dgOP(SimpleMath.Add),new dgOP(new SimpleMath().Sub)) as dgOP;
//执行调用列表的函数,但最终只返回最后一个函数调用返回值。
//dg(10 , 20)内部隐式调用 dg.Invoke(20 , 10)
Tools.OutputParams(dg( , ));
Tools.OutputParams(dg.Invoke(, ));
//DisplayDelegate(dg);
Tools.NewLine(); ////动态方法
//SimpleMath m=new SimpleMath();
//dgOP dg2 = new dgOP(m.Sub);
//Tools.OutputParams(dg2(10,20),dg2.Invoke(20,10));
//DisplayDelegate(dg2);
////委托已经声明为方法签名为:void Fun(int x,int y),对应2个参数
////SimpleMath.Square只含一个参数
////dgOP dg3 = new dgOP(SimpleMath.Square); Tools.Pause();
} private static void Del(dgOP dgOP)
{
dg += dgOP;
} private static dgOP Del()
{
dgOP dg = new dgOP(SimpleMath.Add);
dg += new dgOP(new SimpleMath().Sub);
return dg;
} private static void DisplayDelegate(dgOP dg)
{
//输出委托列表内部的方法签名,类对象
foreach (Delegate item in dg.GetInvocationList())
{
Tools.OutputParams(item.Method, item.Target);
}
} }
}
Tools类只是个工具,用来输出值至控制台,或者另起一行,停止控制台。
委托是最底层,事件是较上层,用来简化处理委托声明,封装维护调用列表。
#region Using directives using System;
using System.Collections.Generic;
using System.Text; #endregion namespace CarEvents
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Fun with Events *****\n"); // Make a car as usual.
Car c1 = new Car("SlugBug", , ); // Register event handlers.
c1.AboutToBlow += new Car.CarEventHandler(c1_AboutToBlow);
c1.AboutToBlow += new Car.CarEventHandler(CarIsAlmostDoomed);
c1.AboutToBlow += new Car.CarEventHandler(CarAboutToBlow); Car.CarEventHandler d = new Car.CarEventHandler(CarExploded);
c1.Exploded += d; // Speed up (this will generate the events.)
Console.WriteLine("***** Speeding up *****");
for (int i = ; i < ; i++)
c1.Accelerate(); // Remove CarExploded method
// from invocation list.
c1.Exploded -= d; Console.WriteLine("\n***** Speeding up *****");
for (int i = ; i < ; i++)
c1.Accelerate(); Console.ReadLine();
} static void c1_AboutToBlow(string msg)
{
Console.WriteLine("xxxx");
} public static void CarAboutToBlow(string msg)
{ Console.WriteLine(msg); } public static void CarIsAlmostDoomed(string msg)
{ Console.WriteLine("Critical Message from Car: {0}", msg); } public static void CarExploded(string msg)
{ Console.WriteLine(msg); } }
} #region Using directives using System;
using System.Collections.Generic;
using System.Text; #endregion namespace CarEvents
{
public class Car
{
//// This delegate works in conjunction with the
//// Car’s events.
//public delegate void CarEventHandler(string msg); //// This car can send these events.
//public event CarEventHandler Exploded;
//public event CarEventHandler AboutToBlow; public delegate void CarEventHandler(string msg); public event CarEventHandler Exploded;
public event CarEventHandler AboutToBlow;
#region Basic Car members... #region Nested radio
// Radio as nested type
public class Radio
{
public void TurnOn(bool on)
{
if (on)
Console.WriteLine("Jamming...");
else
Console.WriteLine("Quiet time...");
}
}
#endregion // Internal state data.
private int currSpeed;
private int maxSpeed;
private string petName; // Is the car alive or dead?
bool carIsDead; // A car has-a radio.
private Radio theMusicBox = new Radio(); public Car()
{
maxSpeed = ;
} public Car(string name, int max, int curr)
{
currSpeed = curr;
maxSpeed = max;
petName = name;
} public void CrankTunes(bool state)
{
theMusicBox.TurnOn(state);
}
#endregion #region Accelerate method
public void Accelerate(int delta)
{
// If the car is dead, fire Exploded event.
if (carIsDead)
{
if (Exploded != null)
Exploded("Sorry, this car is dead...");
}
else
{
currSpeed += delta; // Almost dead?
if ( == maxSpeed - currSpeed
&& AboutToBlow != null)
{
AboutToBlow("Careful buddy! Gonna blow!");
} // Still OK!
if (currSpeed >= maxSpeed)
carIsDead = true;
else
Console.WriteLine("->CurrSpeed = {0}", currSpeed);
}
}
#endregion }
}
匿名方法是简化了委托及方法定义,不必再手动定义方法,直接间写在委托中。
#region Using directives using System;
using System.Collections.Generic;
using System.Text; #endregion namespace AnonymousMethods
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Anonymous Methods *****"); int aboutToBlowCounter = ; // Make a car as usual.
Car c1 = new Car("SlugBug", , ); // Register event handlers as anonymous methods.
c1.AboutToBlow += delegate
{
aboutToBlowCounter++;
Console.WriteLine("Eek! Going too fast!");
}; c1.AboutToBlow += delegate(object sender, CarEventArgs e)
{
aboutToBlowCounter++;
Console.WriteLine("Message from Car: {0}", e.msg);
}; c1.Exploded += delegate(object sender, CarEventArgs e)
{ Console.WriteLine("Message from Car: {0}", e.msg); }; // Speed up (this will generate the events.)
Console.WriteLine("\n***** Speeding up *****");
for (int i = ; i < ; i++)
c1.SpeedUp(); Console.WriteLine("AboutToBlow event was fired {0} times",
aboutToBlowCounter); Console.ReadLine();
}
}
}
#region Using directives using System;
using System.Collections.Generic;
using System.Text; #endregion namespace AnonymousMethods
{
//与上面的事件代码类似
public class CarEventArgs : EventArgs
{
public readonly string msg;
public CarEventArgs(string message)
{
msg = message;
}
} public class Car
{
// This delegate works in conjunction with the
// Car’s events.
public delegate void CarEventHandler(object sender, CarEventArgs e); // This car can send these events.
public event CarEventHandler Exploded;
public event CarEventHandler AboutToBlow; #region Basic Car members...
#region Nested radio
// Radio as nested type
public class Radio
{
public void TurnOn(bool on)
{
if (on)
Console.WriteLine("Jamming...");
else
Console.WriteLine("Quiet time...");
}
}
#endregion // Internal state data.
private int currSpeed;
private int maxSpeed;
private string petName; // Is the car alive or dead?
bool carIsDead; // A car has-a radio.
private Radio theMusicBox = new Radio(); public Car()
{
maxSpeed = ;
} public Car(string name, int max, int curr)
{
currSpeed = curr;
maxSpeed = max;
petName = name;
} public void CrankTunes(bool state)
{
theMusicBox.TurnOn(state);
}
#endregion public void SpeedUp(int delta)
{
// If the car is dead, fire Exploded event.
if (carIsDead && Exploded != null)
{
Exploded(this, new CarEventArgs("Sorry, this car is dead..."));
}
else
{
currSpeed += delta; // Almost dead?
if ( == maxSpeed - currSpeed
&& AboutToBlow != null)
{
AboutToBlow(this, new CarEventArgs("Careful buddy! Gonna blow!"));
} // Still OK!
if (currSpeed >= maxSpeed)
carIsDead = true;
else
Console.WriteLine("->CurrSpeed = {0}", currSpeed);
}
}
}
}
而lambdar表达式则是对匿名方法的再次简化,由此可以引申出linq,ef的语法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace SimpleLambdaExpressions
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Fun with Lambdas *****\n");
TraditionalDelegateSyntax();
AnonymousMethodSyntax(); Console.WriteLine();
LambdaExpressionSyntax(); Console.ReadLine();
} #region Traditional delegate syntax
static void TraditionalDelegateSyntax()
{
// Make a list of integers.
List<int> list = new List<int>();
list.AddRange(new int[] { , , , , , }); // Call FindAll() using traditional delegate syntax.
Predicate<int> callback = new Predicate<int>(IsEvenNumber);
List<int> evenNumbers = list.FindAll(callback); Console.WriteLine("Here are your even numbers:");
foreach (int evenNumber in evenNumbers)
{
Console.Write("{0}\t", evenNumber);
}
Console.WriteLine();
}
// Target for the Predicate<> delegate.
static bool IsEvenNumber(int i)
{
// Is it an even number?
return (i % ) == ;
}
#endregion #region Anonymous method syntax
static void AnonymousMethodSyntax()
{
// Make a list of integers using C# 3.0
// collection initialization syntax.
List<int> list = new List<int>();
list.AddRange(new int[] { , , , , , }); List<int> evenNumbers = list.FindAll(
delegate(int i)
{
return (i % ) == ;
}
); Console.WriteLine("Here are your even numbers:");
foreach (int evenNumber in evenNumbers)
{
Console.Write("{0}\t", evenNumber);
}
Console.WriteLine();
}
#endregion #region Lambda expression syntax
static void LambdaExpressionSyntax()
{
// Make a list of integers.
List<int> list = new List<int>();
list.AddRange(new int[] { , , , , , }); // Now process each argument within a group of
// code statements.
List<int> evenNumbers = list.FindAll((i) =>
{
Console.WriteLine("value of i is currently: {0}", i);
bool isEven = ((i % ) == );
return isEven;
}); Console.WriteLine("Here are your even numbers:");
foreach (int evenNumber in evenNumbers)
{
Console.Write("{0}\t", evenNumber);
}
Console.WriteLine();
}
#endregion
}
}
总结性的比较少,代码比较多。因为我还没有完全领悟,只是初步了解了下。
具体大家可以发挥google的优势。
C#委托初探的更多相关文章
- <.net>委托初探
最近在学<.net深入体验与实战精要>. 今天就来初步讲解下委托. 一句话:委托定义了方法类型,可以将方法当做另一个方法的参数进行传递.委托包涵的只是方法的地址,而不是数据.类似于c指针. ...
- C#委托与事件初探
最近刚刚接触C#,学到事件与委托部分无法理解,于是上网查阅了各种资料,终于明白了一些,在此进行总结. 一.C语言中的函数指针 想要理解什么是委托,就要先理解函数指针的概念.所谓函数指针,就是指向函数的 ...
- 匹夫细说C#:委托的简化语法,聊聊匿名方法和闭包
0x00 前言 通过上一篇博客<匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的>的内容,我们实现了使用委托来构建我们自己的消息系统的过程.但是在日常的开发中,仍然有很多开发者因为 ...
- C#委托与事件的简单使用
前言:上一篇博文从原理和定义的角度介绍了C#的委托和事件.本文通过一个简单的小故事,来说明C#委托与事件的使用方法及其方便之处. 在阅读本文之前,需要你对委托和事件的基本概念有所了解.如果你是初次接触 ...
- C#多线程之旅(4)——APM初探
源码地址:https://github.com/Jackson0714/Threads 原文地址:C#多线程之旅(4)——APM初探 C#多线程之旅目录: C#多线程之旅(1)——介绍和基本概念 C# ...
- (转)初探Backbone
(转)http://www.cnblogs.com/yexiaochai/archive/2013/07/27/3219402.html 初探Backbone 前言 Backbone简介 模型 模型和 ...
- 26.QT-模型视图之自定义委托
在上一章学习 25.QT-模型视图 后,本章接着学习视图委托 视图委托(Delegate)简介 由于模型负责组织数据,而视图负责显示数据,所以当用户想修改显示的数据时,就要通过视图中的委托来完成 视图 ...
- VB 共享软件防破解设计技术初探(三)
×××××××××××××××××××××××××××××××××××××××××××××× 其他文章快速链接: VB 共享软件防破解设计技术初探(一)http://bbs.pediy.com/sho ...
- Spring IOC容器启动流程源码解析(一)——容器概念详解及源码初探
目录 1. 前言 1.1 IOC容器到底是什么 1.2 BeanFactory和ApplicationContext的联系以及区别 1.3 解读IOC容器启动流程的意义 1.4 如何有效的阅读源码 2 ...
随机推荐
- 监控Spark应用方法简介
监控Spark应用有很多种方法. Web接口每一个SparkContext启动一个web UI用来展示应用相关的一些非常有用的信息,默认在4040端口.这些信息包括: 任务和调度状态的列表RDD大小和 ...
- 【HTML5】表单元素
* datalist datalist 元素规定输入域的选项列表. 列表是通过 datalist 内的 option 元素创建的. 如需把 datalist 绑定到输入域,请用输入域的 list 属性 ...
- Xamarin Visual Studio提示找不到AssemblyAttributes.cs文件
Xamarin Visual Studio提示找不到AssemblyAttributes.cs文件 错误信息:Could not find file ‘C:\Users\[用户名]\AppDat ...
- Python核心模块——urllib模块
现在Python基本入门了,现在开始要进军如何写爬虫了! 先把最基本的urllib模块弄懂吧. urllib模块中的方法 1.urllib.urlopen(url[,data[,proxies]]) ...
- BZOJ3103 : Palindromic Equivalence
用Manacher可以推出O(n)对相等和不等关系. 将相等的用并查集维护,不等的连边. 然后从1到n,如果该等价类还没被考虑过,则ans*=26-与它不等的考虑过的等价类个数. #include&l ...
- BZOJ3796 : Mushroom追妹纸
将S1与S2用#号拼接在一起形成S串 将S3与S串跑KMP求出S3在S串中每次出现的位置l[i] 对于S串每个后缀i,求出f[i]表示该串不包含S3串的最长前缀 然后求出S串的后缀数组 先从小到大扫描 ...
- COJ885 LCS???
试题描述 输入两个字符串A.B,输出他们的最长连续公共子串长度. 输入 第一行为一个字符串A. 第二行为一个字符串B. 输出 输出他们的最长连续公共子串长度. 输入示例 ababab bababbab ...
- Memcached、Redis OR Tair
一.前言 非关系型数据库(NoSQL = Not Only SQL)的产品非常多,常见的有Memcached.Redis.MongoDB等优秀开源项目,相关概念和资料网上也非常丰富,不再重复描述,本文 ...
- win95+ie3-win10+ie11 浏览器执行漏洞
alliedve.htm <!doctype html><html><meta http-equiv="X-UA-Compatible" conten ...
- checking在浏览器为应用缓存查找更新时触发
离线的Web应用,就是在设备不能上网的时候还能运行应用.html5把离线应用作为重点,主要是开发人员的心愿.离线应用的开发的步骤有:首先应该知道设备是否能够上网;然后应该还能访问一定的资源(如图像.C ...