gpt4 book ai didi

解析.Net 4.0 中委托delegate的使用详解

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 26 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章解析.Net 4.0 中委托delegate的使用详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

.Net中的委托从功能上讲和c语言或者c++中的方法指针类似,可以像调用方法一样调用委托完成某个功能,或返回某类结果。但是.Net毕竟是更高级的语言,委托Delegate也更高级了,委托是一种数据接口,它包含调用目标和调用方法的指针;而在.Net中定义的委托都继承自MulticastDelegate即多播委托,所谓的多播委托是指可以包含多个调用方法的委托。 一. 先来看下委托的定义: 如下C#代码定义委托 public delegate void DoSomething(int times); 委托的定义包含5个部分 1) public表示委托的可访问性 2) delegate关键字表示要定义一个委托 3) void表示委托定义方法的返回值 4) DoSomething是委托的名字 5) (int times) 是委托方法的参数列表,此处的参数列表可以包括ref参数,也可以有out参数,同样也可以有parms可变数量参数;需要注意如果委托中有多个调用方法,使用out参数时只能返回委托最后执行成功的一个委托方法的计算值 在C#中定义委托非常简单,只比方法定义的返回值之前多一个delegate关键字即可。 可是我们知道所有的用户定义委托都继承自MulticastDelegate;而MulticastDelegate是一个类;所以自定义的委托肯定也是一个类;看下上述代码的IL代码就可以证明我们的推断:

复制代码代码如下

.class public auto ansi sealed delegates.DoSomething     extends [mscorlib]System.MulticastDelegate {     // Methods     .method public hidebysig specialname rtspecialname         instance void .ctor (             object 'object',             native int 'method'         ) runtime managed     {     } // end of method DoSomething::.ctor     .method public hidebysig newslot virtual         instance void Invoke (             int32 times         ) runtime managed     {     } // end of method DoSomething::Invoke       .method public hidebysig newslot virtual         instance class [mscorlib]System.IAsyncResult BeginInvoke (             int32 times,             class [mscorlib]System.AsyncCallback callback,             object 'object'         ) runtime managed     {     } // end of method DoSomething::BeginInvoke       .method public hidebysig newslot virtual         instance void EndInvoke (             class [mscorlib]System.IAsyncResult result         ) runtime managed     {     } // end of method DoSomething::EndInvoke } // end of class delegates.DoSomething 。

二. 定义了委托,当然是为了使用它,来看下如何使用委托: 在.Net中有三种委托的形式,分别是方法、匿名方法和lambda表达式;我们用方法定义的形式看下委托的使用方法 。

复制代码代码如下

using System; namespace delegates {  public delegate void DoSomething(int times);     class Program     {         static void Main(string[] args)         {             //声明委托变量并给委托变量赋值             DoSomething @do = DoA;             //可以使用+号或者+=给委托增加方法             @do += DoB;             //执行委托时将按照委托的添加顺序先后执行委托中的方法             @do(1);             //也可以通过-号或者-= 从委托中移除方法             @do -= DoA;             @do(2);             @do -= DoB;             //将委托中的所有方法都移除掉之后,委托照样是可以调用的,只是什么都不做             @do(3);             Console.Read();         }        //定义一个委托相同参数和返回值的方法         static void DoA(int times)         {             Console.WriteLine("Do A {0}", times);         }           //定义一个委托相同参数和返回值的方法         static void DoB(int times)         {             Console.WriteLine("Do B {0}", times);         }     } } 。

如上代码中的Main方法,首先我们定义了委托DoSomething的变量@do,并将DoA方法直接赋值给此委托变量;然后我们又使用+=符号或者+号给此委托添加了另一个方法;当然也可以使用-或者-=从委托中去掉方法。 委托比C/C++方法指针强大的地方在于其可以容纳多个方法,也可以执行+/-操作从方法列表中添加或者删除掉方法。 在执行委托加减运算时有几个问题需要我们注意: 1. 委托声明的写法 委托声明时可以用如下写法 。

复制代码代码如下

DoSomething @do = DoA,

这其实是一种简短的写法,我们知道在.Net 1.x中这样写是不允许的只有到.Net 2.0时才允许这么写,在.Net 1.x中必须写成 。

复制代码代码如下

DoSomething @do = new DoSomething(DoA),

我们要在声明时就给@do赋予DoA加上DoB 。

复制代码代码如下

DoSomething @do = DoA + DoB,

这么写是不行的,编译器不干了;必须使用.Net 1.x中的写法 。

复制代码代码如下

DoSomething @do = new DoSomething(DoA) + new DoSomething(DoB),

2. 从委托中减去委托中本不存在的方式时会发生什么呢? 请看如下代码:

复制代码代码如下

DoSomething @do = DoA; @do -= DoB,

第一行代码我生命了@do并将DoA赋予它;第二行代码我尝试从@do中减去DoB,DoB并没有在@do的方法列表中存在,这样会发生什么情况呢?首先编译器没有报错,程序可以正常的编译;执行代码发现可以程序可以正常执行,调用@do委托时正确的执行了DoA方法;这说明了.Net包容了我们程序员犯的错,我们从委托变量中减去一个委托中并不包含的方法时,不会报错会正常的执行。 3. 对委托做减法,所有委托都减完了,会怎样呢?看如下代码 。

复制代码代码如下

DoSomething @do = new DoSomething(DoA) + new DoSomething(DoB); @do -= DoA; @do -= DoB; @do(1),

这样的代码可以成功编译,但是在运行时会报NullReferenceException;这显然不是我们希望的,所以对委托做减法时要特别注意.

复制代码代码如下

<span style="text-decoration: line-through;">public delegate void DoIt(string task); class Test {     static void Main(string[] args)     {         //DoIt声明,赋予一个参数更宽泛的方法是合法的         DoIt doIt = new DoIt(DoItImpl);         doIt("hello");     }     //比委托定义中的参数更宽泛,string类型可以隐式转换成object     static void DoItImpl(object task)     {         Console.WriteLine("DoItImpl {0}",task);     } } </span> 。

最后此篇关于解析.Net 4.0 中委托delegate的使用详解的文章就讲到这里了,如果你想了解更多关于解析.Net 4.0 中委托delegate的使用详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com