C#委托初探

时间:2023-01-14 00:02:21

委托是一种定义方法签名的类型,可以与具有兼容签名的任何方法关联。您可以通过委托调用其中已添加的方法列表。委托用于将方法作为参数传递给其他方法。事件处理程序就是通过委托调用的方法。您可以创建一个自定义方法,当发生特定事件时某个类(例如 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#委托初探的更多相关文章

  1. &lt&semi;&period;net&gt&semi;委托初探

    最近在学<.net深入体验与实战精要>. 今天就来初步讲解下委托. 一句话:委托定义了方法类型,可以将方法当做另一个方法的参数进行传递.委托包涵的只是方法的地址,而不是数据.类似于c指针. ...

  2. C&num;委托与事件初探

    最近刚刚接触C#,学到事件与委托部分无法理解,于是上网查阅了各种资料,终于明白了一些,在此进行总结. 一.C语言中的函数指针 想要理解什么是委托,就要先理解函数指针的概念.所谓函数指针,就是指向函数的 ...

  3. 匹夫细说C&num;:委托的简化语法,聊聊匿名方法和闭包

    0x00 前言 通过上一篇博客<匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的>的内容,我们实现了使用委托来构建我们自己的消息系统的过程.但是在日常的开发中,仍然有很多开发者因为 ...

  4. C&num;委托与事件的简单使用

    前言:上一篇博文从原理和定义的角度介绍了C#的委托和事件.本文通过一个简单的小故事,来说明C#委托与事件的使用方法及其方便之处. 在阅读本文之前,需要你对委托和事件的基本概念有所了解.如果你是初次接触 ...

  5. C&num;多线程之旅&lpar;4&rpar;——APM初探

    源码地址:https://github.com/Jackson0714/Threads 原文地址:C#多线程之旅(4)——APM初探 C#多线程之旅目录: C#多线程之旅(1)——介绍和基本概念 C# ...

  6. &lpar;转&rpar;初探Backbone

    (转)http://www.cnblogs.com/yexiaochai/archive/2013/07/27/3219402.html 初探Backbone 前言 Backbone简介 模型 模型和 ...

  7. 26&period;QT-模型视图之自定义委托

    在上一章学习 25.QT-模型视图 后,本章接着学习视图委托 视图委托(Delegate)简介 由于模型负责组织数据,而视图负责显示数据,所以当用户想修改显示的数据时,就要通过视图中的委托来完成 视图 ...

  8. VB 共享软件防破解设计技术初探(三)

    ×××××××××××××××××××××××××××××××××××××××××××××× 其他文章快速链接: VB 共享软件防破解设计技术初探(一)http://bbs.pediy.com/sho ...

  9. Spring IOC容器启动流程源码解析&lpar;一&rpar;——容器概念详解及源码初探

    目录 1. 前言 1.1 IOC容器到底是什么 1.2 BeanFactory和ApplicationContext的联系以及区别 1.3 解读IOC容器启动流程的意义 1.4 如何有效的阅读源码 2 ...

随机推荐

  1. socket - socketserver - start TCP server

    前面提到如何使用socket模块启动tcpserver: 创建socket:sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 绑定ip: ...

  2. IP验证正则表达式

    Regex r = new Regex(@"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$" ...

  3. Visual Studio 2010 实用功能&colon;使用web&period;config发布文件替换功能

    当建立ASP.NET Web应用程序项目后,默认除了生成web.config外,还生成了web.debug.config与Web.Release.config.顾名思义,根据它们的命名我可以推测到他们 ...

  4. 《Java JDK7 学习笔记》课后练习题2

    1.如果在hello.java中撰写以下的程序代码: public class Hello {     public static dmain(String[]args) {          Sys ...

  5. trace enabled

    <system.web> <trace enabled="true" localOnly="true" pageOutput="tr ...

  6. 1&period;PHP站内搜索 分类: PHP开发实例 2015-07-31 22&colon;48 4人阅读 评论&lpar;0&rpar; 收藏

    PHP站内搜索:多关键字.加亮显示 1.SQL语句中的模糊查找 $sql = "SELECT * FROM `message` WHERE `content`like '%$k[0]%' a ...

  7. curl 报错记录,mark

    今天在做接口开发的时候,使用curl post ,请求返回数据为 null ,很纳闷,然后使用 curl_errno 打印出来的错误代码为 28 ,curl_error($ch) 打印出来的是Oper ...

  8. 关于java mail 发邮件的问题总结(转)

    今天项目中有需要用到java mail发送邮件的功能,在网上找到相关代码,代码如下: import java.io.IOException; import java.util.Properties; ...

  9. 前后端分离与 restful api

    为什么要前后端分离(优点): PC,APP,PAD 多端适应 单页面应用(Single Page Application)SPA开发模式开始流行 前后端开发职责不清 开发效率问题,前后端互相等待 前端 ...

  10. tomcat6url请求400错误&lpar;&percnt;2F与&percnt;5C&rpar;

    近期几天,开发接口时.tomcat报了400错误,查了下原因. 错误原因:url中參数部分包括/,默认tomcat是不支持url參数包括: /(%2F),\(%5C). 解析方法:能够通过加入配置Do ...