当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > C#教程:没有扩展方法的日子

ASP.NET
赫赫大名的A*寻路算法(vb.net版本)
asp.net(c#)下Jmai去说明 使用与下载
[原创]完美解决Could not load file or assembly ''AjaxPro.2'' or one of its dependencies. 拒绝访问。
asp.net下gridview 批量删除的实现方法
用CSS实现图片倾斜 只支持IE
.net get set用法小结
vs 不显示行号的操作方法
ASP.NET页面进行GZIP压缩优化的几款压缩模块的使用简介及应用测试!(附源码)
ASP.Net不执行问题一解
asp.net 无限分类
让VS2008对JQuery语法的智能感知更完美一点
扩展方法ToJSON() and ParseJSON()
asp.net下PageMethods使用技巧
Linq to SQL Delete时遇到问题的解决方法
实现ASP.NET多文件上传程序代码
ASP.NET AJAX 1.0 RC开发10分钟图解
asp.net get set用法
ASP.NET下使用WScript.Shell执行命令
asp.net2.0实现邮件发送(测试成功)
Asp.net 无限级分类实例代码

ASP.NET 中的 C#教程:没有扩展方法的日子


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 87 ::
收藏到网摘: n/a

没有扩展方法的日子

如果在开始使用C# 3之前你已经编写了很多的C# 2代码, 你应该看一下你的静态类——它们中的大多数都是可以被转换成扩展方法的候选. 这并不是说所有已经存在的静态类都适合, 但你可以透过下面的特征来认出它:

  • 你想增加成员到一个类型上
  • 你不需要增加任何的数据到类型实例上
  • 你不能改变类型本身, 因为它来自于其他人的代码

另一种情况你可能也想可以使用接口来代替具体类型, 然后添加一些有用的方法到接口上面, 并通过接口来调用也可以实现类似的要求. 一个好的例子就是IList<T>. 如果它能够对所有实现了IList的类型进行排序那应该会是非常美妙的事情, 然而这会要求所有的接口实现都要实现如何对它们自己排序, 这是非常可怕的. 当然从用户的角度来看还是相当不错的.

问题是IList<T>已经提供了一个完整的泛型排序例程, 但是我们却不能将完整的实现放在该接口中(接口不能有实现). 我们当然可以将其指定为抽象类, 这样就可以包含排序的实现了, 但.NET和C#只允许单继承, 这将会严重限制那些从它继承出去的类型. 扩展方法可以允许我们排序任何IList<T>的实现, 看起来就像是它本身就提供了这个功能一样.

接下来让我们来看一个例子, Stream类是.NET当中二进制通讯的基础, Stream本身是一个抽象类, .NET Framework包含有几个具体的实现类, 例如NetworkStream, FileStream, MemoryStream. 不幸的是, 有些个功能本该被包含在Stream当中, 然而实际上它们并没有.

最常见的缺失功能是读取一个流到内存当中并且保存为二进制数组的功能以及将一个流的内容拷贝到另外一个当中. 如果能将它们集中实现, 避免在不同的项目之间复制一些糟糕的实现无疑将会是是很不错的主意. 下面的代码提供了我们提到的这些额外的对Stream的功能要求.

 1: using System.IO;
 2: public static class StreamUtil
 3: {
 4: const int BufferSize = 8192;
 5: public static void Copy(Stream input,Stream output)
 6: {
 7: byte[] buffer = new byte[BufferSize];
 8: int read;
 9: while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
 10: {
 11: output.Write(buffer, 0, read);
 12: }
 13: }
 14: public static byte[] ReadFully(Stream input)
 15: {
 16: using (MemoryStream tempStream = new MemoryStream())
 17: {
 18: Copy(input, tempStream);
 19: return tempStream.ToArray();
 20: }
 21: }
 22: }

这个工具类本身并没有太多东西需要解读, 仅仅是为了方便之后引入扩展方法, 接下来看看我们如何使用这个工具类:

 1: WebRequest request = WebRequest.Create("http://manning.com");
 2: using (WebResponse response = request.GetResponse())
 3: using (Stream responseStream = response.GetResponseStream())
 4: using (FileStream output = File.Create("response.dat"))
 5: {
 6: StreamUtil.Copy(responseStream, output);
 7: }

上面的代码已经是很简洁的了, StramUtil会自动循环接受流当中所有的数据, 其很好的完成了工作. 唯一的一点就是看起来不是那么面向对象, 我们更喜欢能够让响应的数据流拷贝自己到输出流当中, 就像MemeryStream自己的WriteTo方法一样. 这不是什么大问题, 仅仅是有一点丑陋.