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

ASP.NET
Visual Studio.Net 内幕(7)
.Net 2.0 原汁原味读取注册表
ASP.NET 2.0中预设的cookie
ASP.NET:一段比较经典的多线程学习代码
ASP.NET2.0服务器控件之自定义状态管理
Asp.net给站点某目录增加Aspnet用户
ASP.NET技巧:请求网址并解析返回的html
在Asp.net用C#建立动态Excel
ASP.NET2.0:页面中链入的CSS、js文件带中文时需注意
ASP.NET技巧:数据岛出到Excel最为简易的方法
第一次用.net2.0 LOGIN登陆控件的困惑和解决方法
在ASP.net中保存/取出图片入/从SQL数据库
ASP.NET技巧:做个DataList可分页的数据源
在.NET中利用委托实现窗体间通信
在.NET2.0中使用自定义事务操作
解决 ASP.NET中目录访问权限的问题
ASP.Net防止刷新自动触发事件的解决方案
白刃之战:PHP vs. ASP.NET(节选)-架构比较
C#中使用SendMessage
提取HTML代码中文字的C#函数

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


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