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

ASP.NET
为T-SQL添加intellisense功能
SQL Server 2005安装过程中出现错误的解决办法
SQL Server 2005 RTM 安装错误 :The SQL Server System Configuration Checker cannot be executed due to
有关于JSON的一些资料
不能忽略c#中的using和as操作符的用处
JavaScript系列之―同步还是异步?
获取远程网页的内容之一(downmoon原创)
获取远程网页的内容之二(downmoon原创)
ASP.Net中防止刷新自动触发事件的解决方案
asp.net下用js实现鼠标移至小图,自动显示相应大图
Asp.Net 和 AJAX.Net 的区别
提交页面的定位--scrollIntoView的用法
利用AJAX与数据岛实现无刷新绑定
asp.net下判断用户什么时候离开,以什么方式离开
DataSet 添加数据集、行、列、主键和外键等操作示例
读写xml所有节点个人小结 和 读取xml节点的数据总结
收藏的asp.net文件上传类源码
asp.net下GDI+的一些常用应用(水印,文字,圆角处理)技巧
一个可以让.net程序在非WIN平台上运行的软件Mono
使用ASP.NET 2.0 CSS 控件适配器生成CSS友好的HTML输出

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 41 ::
收藏到网摘: 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方法一样. 这不是什么大问题, 仅仅是有一点丑陋.