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

ASP.NET
给Asp.Net初学者的关于继承和多态性的例子
新手入门:C++下的引用类型
初学者的福音:游戏开发新手入门指南
C/C++中利用空指针简化代码,提高效率
获取转向地址的URL的源文件(可自定义REFER)
asp.net中执行存储数据操作时数据被自动截取的一种情况
.NET中防止Access数据库下载
vs.Net2003无法打开或创建Web应用程序若干解决办法.
我今天开始正式学习.net遇到的问题
无法在Web服务器上启动调试。未将项目配置为进行调试
找不到类型或命名空间名称“Server”(是否缺少 using 指令或程序集引用?)
ASP.NET页面间的传值的几种方法
几个ASP.NET技巧
让Asp.NET的DataGrid可排序、可选择、可分页
web.config文件的中文解释
用DataReader还是DataSet?
ASP.NET中数据库操作初步
ExecuteReader(),ExecuteNonQuery(),ExecuteScalar(),ExecuteXmlReader()之间的区别
如何在DataGrid控件中实现自定义分页
ADO.NET 的最佳实践技巧

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


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