知识大全 .NET 委托
Posted 类型
篇首语:炒沙作縻终不饱,缕冰文章费工巧。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 .NET 委托相关的知识,希望对你有一定的参考价值。
.NET 委托 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
委托类型定义
C#编译器处理委托时 先自动产生一个派生自System MulticastDelegate的密封类 这个类与它的基类System Delegate一起为委托提供必要的基础设施 以维护以后将要调用的方法列表 它含有 个编译器生成的方法 这 个方法的参数与返回值基于委托的声明
public sealed class DelegateName System MulticastDelegate public DReturnType Invoke (DParams); public IAsyncResult BeginInvoke(DParams AsyncCallback cb object state); public DReturnType EndInvoke(DRefAndOutParams IAsyncResult result);委托类型实例
某种类型的实例方法和可分配给该类型的目标对象
某种类型的实例方法(包含在形参表中公开的隐藏 this 参数) 该委托称为开放式实例委托
静态方法
静态方法和可分配给该方法的第一个参数的目标对象 该委托称为通过其第一个参数关闭
何时使用委托而不使用接口
委托和接口都允许类设计器分离类型声明和实现 给定的接口可由任何类或结构继承和实现;可以为任何类中的方法创建委托 前提是该方法符合委托的方法签名 接口引用或委托可由不了解实现该接口或委托方法的类的对象使用 既然存在这些相似性 那么类设计器何时应使用委托 何时又该使用接口呢?
在以下情况中使用委托
当使用事件设计模式时
当封装静态方法可取时
当调用方不需要访问实现该方法的对象中的其他属性 方法或接口时
需要方便的组合
当类可能需要该方法的多个实现时
在以下情况中使用接口
当存在一组可能被调用的相关方法时
当类只需要方法的单个实现时
当使用接口的类想要将该接口强制转换为其他接口或类类型时
当正在实现的方法链接到类的类型或标识时 例如比较方法
声明委托
声明一个新的委托类型 每个委托类型都描述参数的数目和类型 以及它可以封装的方法的返回值类型 每当需要一组新的参数类型或新的返回值类型时 都必须声明一个新的委托类型
public delegate void ProcessBookDelegate(Book book);
实例化委托
声明了委托类型后 必须创建委托对象并使之与特定方法关联
在上面的示例中 这是通过将 PrintTitle 方法传递给ProcessPaperbackBooks 方法来完成的
bookDB ProcessPaperbackBooks(PrintTitle);
这将创建与静态方法 Test PrintTitle 关联的新委托对象 类似地 对象 totaller 的非静态方法 AddBookToTotal 是按如下方式传递的
bookDB ProcessPaperbackBooks(totaller AddBookToTotal);
调用委托
创建委托对象后 通常将委托对象传递给将调用该委托的其他代码 通过委托对象的名称(后面跟着要传递给委托的参数 括在括号内)调用委托对象
processBook(b);
多路广播委托
本示例演示如何组合多路广播委托 委托对象的一个用途在于 可以使用 + 运算符将它们分配给一个要成为多路广播委托的委托实例 组合的委托可调用组成它的那两个委托 只有相同类型的委托才可以组合 运算符可用来从组合的委托移除组件委托
根据CIL代码可以发现 +=操作符实际上是转换为了一个静态的Delegate Combine()方法的调用 =操作符实际上是转换为了一个静态的Delegate Remove()方法的调用
delegate void Del(string s); class TestClass static void Hello(string s) System Console WriteLine( Hello ! s); static void Goodbye(string s) System Console WriteLine( Goodbye ! s); static void Main() Del a b c d; a = Hello; b = Goodbye; c = a + b; d = c a; System Console WriteLine( Invoking delegate a: ); a( A ); System Console WriteLine( Invoking delegate b: ); b( B ); System Console WriteLine( Invoking delegate c: ); c( C ); System Console WriteLine( Invoking delegate d: ); d( D );
匿名方法
在 之前的 C# 版本中 声明委托的唯一方法是使用命名方法 C# 引入了匿名方法 要将代码块传递为委托参数 创建匿名方法则是唯一的方法
如果使用匿名方法 则不必创建单独的方法 因此减少了实例化委托所需的编码系统开销 例如 如果创建方法所需的系统开销是不必要的 在委托的位置指定代码块就非常有用 启动新线程即是一个很好的示例 无需为委托创建更多方法 线程类即可创建一个线程并且包含该线程执行的代码
button Click += delegate(System Object o System EventArgs e) System Windows Forms MessageBox Show( Click! ); ;
delegate void Del(int x); Del d = delegate(int k) /* */ ;
void StartThread() System Threading Thread t = new System Threading Thread (delegate() System Console Write( Hello ); System Console WriteLine( World! ); ); t Start();
匿名方法可以访问定义他们的方法的本地变量 即匿名方法的外部变量
匿名方法不能访问定义方法中的ref或out参数
匿名方法中的本地变量不能与外部方法的本地变量重名
匿名方法可以访问外部类作用域中的实例变量或静态变量
委托中的协变和逆变
将方法签名与委托类型匹配时 协变和逆变为您提供了一定程度的灵活性
协变也称为宽松委托 协变允许构造一个委托 指向返回类及其相关继承体系的方法
逆变允许方法具有的派生参数类型比委托类型中的更少
协变
本示例演示如何将委托与具有返回类型的方法一起使用 这些返回类型派生自委托签名中的返回类型 由 SecondHandler 返回的数据类型是 Dogs 类型 它是由委托中定义的 Mammals 类型派生的
Foo<父类> = Foo<子类>
class Mammals class Dogs : Mammals class Program public delegate Mammals HandlerMethod(); public static Mammals FirstHandler()return null; public static Dogs SecondHandler()return null; static void Main() HandlerMethod handler = FirstHandler; HandlerMethod handler = SecondHandler;
逆变
本示例演示如何将委托与具有某个类型的参数的方法一起使用 这些参数是委托签名参数类型的基类型 通过逆变 以前必须使用若干个不同处理程序的地方现在只要使用一个事件处理程序即可&# ; 如 现在可以创建一个接收 EventArgs 输入参数的事件处理程序 然后 可以将该处理程序与发送 MouseEventArgs 类型(作为参数)的 Button MouseClick 事件一起使用 也可以将该处理程序与发送 KeyEventArgs 参数的 TextBox KeyDown 事件一起使用
Foo<子类> = Foo<父类>
System DateTime lastActivity; public Form () InitializeComponent(); lastActivity = new System DateTime(); this textBox KeyDown += this MultiHandler; this button MouseClick += this MultiHandler; private void MultiHandler(object sender System EventArgs e) lastActivity = System DateTime Now;
泛型委托
委托可以定义自己的类型参数 引用泛型委托的代码可以指定类型参数以创建已关闭的构造类型 就像实例化泛型类或调用泛型方法一样
public delegate void Del<T>(T item); public static void Notify(int i) Del<int> m = new Del<int>(Notify);
方法组转换
C#提供了一种叫做方法组转换的简便方法 该特性允许我们在调用以委托作为参数的方法时直接提供方法的名称 而不用创建委托对象 此功能适用于具体委托类型和泛型委托类型 并使您可以使用如下简化的语法写入上一行
Del<int> m = Notify;
泛型类内部定义委托使用泛型类类型参数
在泛型类内部定义的委托使用泛型类类型参数的方式可以与类方法所使用的方式相同
class Stack<T> T[] items; int index; public delegate void StackDelegate(T[] items);
引用委托的代码必须指定包含类的类型变量
private static void DoWork(float[] items) public static void TestStack() Stack<float> s = new Stack<float>(); Stack<float> StackDelegate d = DoWork;
泛型委托取代传统装箱拆箱委托
根据典型设计模式定义事件时 泛型委托尤其有用 因为发送方参数可以为强类型 不再需要强制转换成 Object 或反向强制转换
delegate void StackEventHandler<T U>(T sender U eventArgs); class Stack<T> public class StackEventArgs : System EventArgs public event StackEventHandler<Stack<T> StackEventArgs> stackEvent; protected virtual void OnStackChanged(StackEventArgs a) stackEvent(this a); class SampleClass public void HandleStackChange<T>(Stack<T> stack Stack<T> StackEventArgs args) public static void Test() Stack<double> s = new Stack<double>(); SampleClass o = new SampleClass(); s stackEvent += o HandleStackChange;
cha138/Article/program/net/201311/11939相关参考
关于.NET的委托[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! //
asp.net教程-委托(Delegate) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&nbs
通过代码学习C#&.NET——委托使用 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 代码编写及
.NET反射、委托技术与设计模式 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 反射技术与设计模
电话转委托与电话自动委托的区别电话转委托是投资者通过电话委托营业部工作人员中转后进入证交所,营业部根据电话委托内容代为填写委托书,委托人应于成交后办理交割时补行签章;电话自动委托则是营业部将其电脑交易
股票交易的委托(一)委托买卖的方式委托人可以采用当面委托、电话、电报、书信等方式,委托证券公司进行买卖。当面委托是指委托人直接到证券公司,当面以口头形式委托证券公司的办事人员代为买卖,或者填写委托书交
常见的特殊形式委托常见的特殊形式委托有停价委托和授权委托。停价委托是指投资者委托证券商,在证券的价格上升或下降超过所指定的限度时,便按照市场价格买入或卖出证券。停价委托包括停价买进委托和停价卖出委托,
委托买卖股票的方式代理或委托买卖股票的具体方式有:1、当面委托当面委托是客户到证券商的营业所,当面办理委托手续,提出委托买卖有价证券的要求。这是一种传统的委托方式,具有稳定可靠的特点,中小额投资者通常
填单委托的内容在填单委托方式下,投资者必须买一张委托单(通常是l元一张,自助委托方式下委托费也是1元)。在委托单中需要填写的内容主要有:股东代码、资金账号,股票代码(股票名称),买卖性质、委托数量、委
市价委托策略市价委托是最普通最容易执行的一种委托指令,指客户只要求经纪商按交易市场当时的价格买进或卖出证券的委托形态。采用市价委托策略(thepolicyofmarketpriceentrustmen