技术开发 频道

拯救C#2.0,但是我们真做的到吗?

 封装逻辑

 既然没有“扩展方法”,我们要避免静态方法的调用形式,那么就只能在一个类中定义逻辑了。这点并不困难,毕竟在API的设计发展至今,已经进入了关注FluentInterface的阶段,这方面已经积累了大量的实践。于是我们构造一个Enumerable<T>类,封装IEnumerable<T>对象,以此作为扩展的入口: 

publicclassEnumerable<T>

 {

 privateIEnumerable<T>m_source;

 publicEnumerable(IEnumerable<T>source)

 {

 if(source==null)thrownewArgumentNullException("source");

 this.m_source=source;

 }

 ...

 }

 并以此定义所需的Select和Where方法:

publicEnumerable<T>Where(Func<T,bool>predicate)

 {

 if(predicate==null)thrownewArgumentNullException("predicate");

 returnnewEnumerable<T>(Where(this.m_source,predicate));

 }

 privatestaticIEnumerable<T>Where(IEnumerable<T>source,Func<T,bool>predicate)

 {

 foreach(Titeminsource)

 {

 if(predicate(item))

 {

 yieldreturnitem;

 }

 }

 }

 publicEnumerable<TResult>Select<TResult>(Func<T,TResult>selector)

 {

 if(selector==null)thrownewArgumentNullException("selector");

 returnnewEnumerable<TResult>(Select(this.m_source,selector));

 }

 privatestaticIEnumerable<TResult>Select<TResult>(IEnumerable<T>source,Func<T,TResult>selector)

 {

 foreach(Titeminsource)

 {

 yieldreturnselector(item);

 }

 }

 这些扩展都是些高阶函数,也都有延迟效果,相信很容易理解,在此就不多作解释了。在这里我们直接观察其使用方式:

List<int>even=newEnumerable<string>(strArray)

 .Select(delegate(strings){returnInt32.Parse(s);})

 .Where(delegate(inti){returni%2==0;})

 .ToList();

 不知道您对此有何感觉?

 老赵对此并不满意,尤其是和C#3.0相较之下。我们虽然定义了Enumerable封装类,并提供了Select和Where等逻辑,但是由于匿名函数的构造还是较为丑陋。使用delegate构造匿名函数还是引起了不少噪音:

 与JavaScript的function关键字,和VB.NET的Function关键字一样,C#2.0在构造匿名函数时无法省确delegate关键字。

 与C#3.0中的Lambda表达式相比,使用delegate匿名函数缺少了必要的类型推演。

 使用delegate构造匿名函数时必须提供完整的方法体,也就是只能提供“语句”,而不能仅为一个“表达式”,因此return和最后的分号无法省确。

 我们设法拯救C#2.0,但是我们真的做到了吗?

 框架/类库真能弥补语言的生产力吗?

原文地址:http://www.cnblogs.com/jeffreyzhao/archive/2009/06/27/try-to-make-a-better-csharp-2.html

0
相关文章