当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > C#2.0新特性探究之模拟泛型和内置算法

ASP.NET
Asp.net利用JQuery弹出层加载数据代码
asp.net dataview做无限极分类的又一用法
asp.net ckeditor编辑器的使用方法
告别ADO.NET实现应用系统无缝切换的烦恼(总结篇)
asp.net 实现动态显示当前时间(不用javascript不考虑开销)
.net动态显示当前时间(客户端javascript)
asp.net 结合YUI 3.0小示例
asp.net 取消缓存相关问题说明
asp.net 计划任务管理程序实现,多线程任务加载
ASP.NET 跨页面传值方法
asp.net中url地址传送中文参数时的两种解决方案
Asp.net 菜单控件简洁版
asp.net jQuery Ajax用户登录功能的实现
asp.net SharpZipLib的压缩与解压问题
asp.net url重写后页面回传问题
asp.net与Discuz!NT整合集成实例教程
Discuz!NT 3与asp.net 整合的实例教程
测试控制台使用方法
.net 动态标题实现方法
asp.net *.ashx类型的文件使用说明

ASP.NET 中的 C#2.0新特性探究之模拟泛型和内置算法


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

在C#2.0中,匿名方法、IEnumerable接口和匿名方法的合作,使很多的编程任务变得非常的简单,而且写出来的程序非常的优美。

  比如,我们可以写出如下的代码:

List<Book> thelib = Library.getbooks();

List<Book> found = thelib.FindAll(delegate(Book curbook)
{
 if (curbook.isbn.StartsWith("..."))
  return true;
  return false;
});

foreach (Book b in found)
Console.WriteLine(b.isbn);
  这段程序非常简单的展示给我们需要查找的信息,代码也非常的直接易懂。内置的数据结构给了我们强大的算法支持,不过,能不能够为自定义的类定义类似的算法呢?

  比如,如果我有一个自定义的Library类并没有使用List<Book>存储数据,而是使用某种自定义的数据结构,我能不能也让用户使用类似的语法,忽略存储细节的使用匿名委托来实现特定的算法呢?

  答案当然是肯定的,而且在C#中实现这样的功能是非常的简单。

  首先让我们看看FindAll中用到的匿名委托的原型

public delegate bool Predicate<T>(T obj);

  很明显的,上面的代码等于注册了一个搜索的回调,而在List内部定义了某种遍历的机制,从而实现了一个漂亮的算法结构Closure。

  看到了这些,我们就可以定义自己的算法结构了,首先,我定义了一个如下的类

public class MyVec<T>
{
 public static MyVec<T> operator +(MyVec<T> a, T b)
 {
  a._list.Add(b);

  return a;
 }
 public override string ToString()
 {
  StringBuilder builder = new StringBuilder();
  foreach (T a in _list)
  {
   builder.Append(a.ToString());
   builder.Append(",");
  }
  string ret = builder.Remove(builder.Length - 1, 1).ToString();
  return ret;
 }

 public MyVec<T<>findAll(Predicate<T> act)
 {
  MyVec<T:>t2 = new MyVec<T>();
  foreach(T i in _list)
  {
   if (act(i))
   t2._list.Add(i);
  }
  return t2;
 }

 // this is the inner object
 private List<T> _list = new List<T>();
}
  这个类中包含了一个的List<T>结构,主要是为了证实我们的想法是否可行,事实上,任何一个可以支持foreach遍历的结构都可以作为内置的数据存储对象,我们会在后面的例子中给出一个更加复杂的实现。

  下面是用于测试这个实验类的代码:

static void Main(string[] args)
{
 MyVec<int> a = new MyVec<int>();
 a += 12;
 a += 15;
 a += 32;
 MyVec<int> b = a.findAll(delegate(int x)
 {
  if (x < 20) return true; return false;
 }
);

 Console.WriteLine("vection original");
 Console.WriteLine(a.ToString());
 Console.WriteLine("vection found");
 Console.WriteLine(b.ToString());
 Console.ReadLine();
}

  编译,执行,程序输出:

vection original

12,15,32

vection found

32
  和我们预期的完全相同。很明显的,List内部的算法与我们预期的基本相同。

  Predicate<T>仅仅是为了仿照系统的实现而采用的一个委托,事实上可以使用自己定义的任何委托作为回调的函数体。  通过使用IEnumberable接口,可以实现对任意结构的遍历,从而对任何数据结构定义强大的算法支持。