C语言学习网

.NET委托不同版本怎么写

发表于:2022-10-04 作者:安全数据网编辑
编辑最后更新 2022年10月04日,本篇内容主要讲解".NET委托不同版本怎么写",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习".NET委托不同版本怎么写"吧!.NET 1.x中委托的写法委托

本篇内容主要讲解".NET委托不同版本怎么写",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习".NET委托不同版本怎么写"吧!

.NET 1.x中委托的写法

委托,如果不追究细节,从表面上来看我们可以将其通俗地理解为一个安全的"函数指针"。当然,这个函数指针其实也是一个对象,有自己的成员,也会封装了被调用方的上下文等等。至于委托的定义和使用方式,则是这样的:

public delegate int SomeDelegate(string arg1, bool arg2);   public static int SomeMethod(string arg1, bool arg2) { return 0; }   public class SomeClass  {      public int SomeMethod(string a1, bool a2) { return 0; }       public event SomeDelegate SomeEvent;  }   static void Main(string[] args)  {      SomeClass someClass = new SomeClass();      SomeDelegate someDelegate = new SomeDelegate(someClass.SomeMethod);       someClass.SomeEvent += new SomeDelegate(SomeMethod);  }

可见,在.NET 1.x中需要使用new DelegateType(...)的方式来创建一个委托对象。不过,作为委托对象内部的方法它既可以是实例方法,也可以是静态方法。此外,方法只需要匹配委托类型的签名和返回值即可,方法参数的名称不会成为约束。

嗯,就是这么简单。

.NET 2.0中委托的写法

.NET委托引入了范型,且写法略有简化:

public delegate TResult MyFunc(T1 a1, T2 a2);   public static int SomeMethod(string a1, bool a2) { return 0; }   static void Main(string[] args)  {      MyFunc myFunc = SomeMethod;  }

在.NET 2.0中,new DelegateType已经可以省略,开发人员可以直接将方法赋值给一个委托对象的引用。当然,这个改进不值一提,.NET 2.0中委托写法的关键在于引入了"匿名方法":

public static void TestRequest(string url)  {      WebRequest request = HttpWebRequest.Create(url);      request.BeginGetResponse(delegate(IAsyncResult ar)      {          using (WebResponse response = request.EndGetResponse(ar))          {              Console.WriteLine("{0}: {1}", url, response.ContentLength);          }      },      null);  }

匿名方法,简单地说就是内联在方法内部的委托对象,它的关键便在于形成了一个闭包(委托执行时所需的上下文)。如上面的代码中,BeginGetResponse的***个参数(委托)可以直接使用TestRequest方法的参数url,以及方法内的"局部"变量request。如果没有匿名函数这个特性的话,代码写起来就麻烦了,例如在.NET 1.x中您可能就必须这么写:

public static void TestRequest(string url)  {      WebRequest request = HttpWebRequest.Create(url);      object[] context = new object[] { url, request };      request.BeginGetResponse(TestAsyncCallback, context);  }   public static void TestAsyncCallback(IAsyncResult ar)  {       object[] context = (object[])ar.AsyncState;      string url = (string)context[0];      WebRequest request = (WebRequest)context[1];       using (WebResponse response = request.EndGetResponse(ar))      {          Console.WriteLine("{0}: {1}", url, response.ContentLength);      }  }

此时,我们往往会发现,开发人员需要花费大量的精力,为一小部分代码维护一大段上下文。例如在这段代码中,我们会将url和request对象塞入一个object数组中,在回调函数中再通过危险的Cast操作恢复数据。如果您希望"强类型",那么只能为每个回调创建一个新的上下文对象,维护起来可能更加麻烦--要知道,在并行编程,异步调用越来越重要的今天,如果没有匿名方法自动保留上下文的特性,开发人员会为这些"额外工作"疲于奔命的。

可能您会说,匿名方法的可读性不佳,因为需要"内联"。一个方法中内联太多,维护成本就上去了,所以匿名方法并不推荐使用。我想说的是,您错了。如果为了可维护性,要将方法独立拆开,也可以利用匿名方法的优势:

public static void TestRequest(string url)  {      WebRequest request = HttpWebRequest.Create(url);      request.BeginGetResponse(delegate(IAsyncResult ar)      {          TestAsyncCallback(ar, request, url);      }, null);  }   public static void TestAsyncCallback(IAsyncResult ar, WebRequest request, string url)  {      using (WebResponse response = request.EndGetResponse(ar))      {          Console.WriteLine("{0}: {1}", url, response.ContentLength);      }  }

如果借助.NET 3.5中的Lambda表达式,代码可以写的更简单易读:

public static void TestRequest(string url)  {      WebRequest request = HttpWebRequest.Create(url);      request.BeginGetResponse(ar => TestAsyncCallback(ar, request, url), null);  }

到此,相信大家对".NET委托不同版本怎么写"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0