好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

2011 年最佳代码

2011 年最佳代码

c# 扩展方法奇思妙用滥用篇一:改进 2011 年最佳代码

2011-08-08 18:39 by 鹤冲天, 2219 visits, 收藏 , 编辑

今天从 老赵 的文章《 谈谈年度最佳代码“不管你们信不信,反正我信了” 》中学习了 2011 年最佳代码:

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 try 
{
     if  (you.believe(it) || !you.believe(it))
    {
        I.believe(it);
    }
}
 catch  (Exception ex)
{
     throw   new  Exception(" It's a miracle! ");
}
 finally 
{
    it.justHappened();
}

老赵 在文中强调了语义编程,建议大家去看看。

在我看来,第三行代码可以改进一些。

信不信,引申出来听不听、做不做、想不想,隐约中有”或者不”的意味,于是 OrNot 扩展方法在我大脑中出现了。

不过下手之前,还得准备一下:

准备工作

先来准备两个接口,表示上面代码中 you、I、it:

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 public   interface  IPerson
{
     bool  Believe(IThing thing);
}

 public   interface  IThing
{
     void  JustHappened();
}

这三个变量可如下声明:

 1 
 2 
 3 
IThing it =  null ;
IPerson you =  null ;
IPerson I =  null ;
OrNot 扩展方法

我最初的想法是,既然是个扩展,就应该让它应用尽量广泛,于是写出的下面的泛型扩展:

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 public   static   class  Extensions
{
     public   static   bool  OrNot<T>( this  Predicate<T> predicate, T t)
    {
         return  predicate(t) || !predicate(t);
    }
}

不过用起来不方便,如把代码写成下面的样子,是编译不通过的:

 1 
 2 
 3 
 4 
 if (you. Believe .OrNot(it))
{
    I.Believe(it);
}

提示错误:

'IPerson.Believe(IThing)' is a 'method', which is not valid in the given context

只好写成为:

 1 
 2 
 3 
 4 
 5 
Predicate<IThing> youBelieve = you.Believe;
 if (youBelieve.OrNot(it))
{
    I.Believe(it);
}

或者:

 1 
 2 
 3 
 4 
 if  (((Predicate<IThing>)you.Believe).OrNot(it))
{
    I.Believe(it);
}

这两种方式我都看不上眼,不过第二种方式给了一些灵感,于是做了些改进。

改进

上面代码使用了 Predicate<T> 委托,代表输入一个 T 返回一个布尔值。

在本应用中,是输入一个 IThing 返回一个布尔值,可表示为 Predicate<IThing>,写起来太烦索了。

何不就当前语境定义一个新的委托呢?如下:

 1 
 public   delegate   bool    WhatEver   (IThing obj);

相应扩展方法修改为:

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 public   static   class  Extensions
{
     public   static   bool  OrNot( this    WhatEver   func, IThing t)
    {
         return  func(t) || !func(t);
    }
}

代码可写成:

 1 
 2 
 3 
 4 
 if  (((  WhatEver  )  you  .  Believe  ).  OrNot   ( it ))
{
      I  .  Believe  ( it );
}

准确的的表达出了” 不管 你们 信 不信 “的意思。

完整代码:

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 try 
{
     if  (((  WhatEver  )  you  .  Believe  ).  OrNot  ( it ))
    {
          I  .  Believe  ( it );
    }
}
 catch  (Exception ex)
{
     throw   new  Exception(" It's a miracle! ");
}
 finally 
{
    it.JustHappened();
}

再次改进

回复中有朋友问是否可写成 (( WhatEver ) you . Believe ( it ). OrNot (),读起来顺多了。

这样可能不恰当,写成如下道是可以的:

 1 
 2 
 3 
 4 
 if  (  whatEver  (  you  .  Believe  )( it ). OrNot ())
{
      I  .  Believe  ( it );
}

这时 whatEver 是个静态变量:

 1 
 public   static  Func<Predicate<IThing>, Func<IThing, Func< bool >>>   whatEver   = p => i => (() => p(i));

这种方式在我的文章《 借助委托精简代码 》中有提及。

配合如下扩展方法:

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 public   static   class  Extensions
{
     public   static   bool  OrNot( this  Func< bool > func)
    {
         return  func() || !func();
    }
}

完整代码如下:

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 namespace  ImproveBestCodeOf2011
{
     class  Program
    {
         public   static  Func<Predicate<IThing>, Func<IThing, Func< bool >>>   whatEver   = p => i => (() => p(i));
         static   void  Main( string [] args)
        {
            IThing it =  null ;
            IPerson you =  null ;
            IPerson I =  null ;
             if  (  whatEver  (  you  .  Believe  )( it ). OrNot ())
            {
                  I  .  Believe  ( it );
            }
        }
    }
     public   static   class  Extensions
    {
         public   static   bool  OrNot( this  Func< bool > func)
        {
             return  func() || !func();
        }
    }
     public   interface  IPerson
    {
         bool  Believe(IThing thing);
    }
     public   interface  IThing
    {
         void  JustHappened();
    }
}

呵!这种方式又滥用了委托!

小结

使用一段代码结束本文(可跳过):

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 static   void  Main( string [] args)
{
    IThing it =  new   OrNotExtensionIsTheBestOf2011 ();
    IPerson you =  new  Person { Name = " 看本文的你 " };
    IPerson I =  new  Person { Name = " 鹤冲天 " };

     if  (((  WhatEver  )  you  .  Believe  ).  OrNot  (it))
    {
          I  .  Believe  (it);
    }
     //or  
     if  (  whatEver  (    you  .  Believe  )( it ).  OrNot  ())
    {
          I  .  Believe  (it);
    }

 }

 public   class   OrNotExtensionIsTheBestOf2011 : IThing
{
     public   string  Title
    { 
         get  {  return  " OrNot 扩展方法是 2011 年最佳扩展 "; }
    }

     public   void  JustHappened()
    {
        Console.WriteLine(" OrNot 扩展方法被评为 2011 年最佳扩展 ");
    }
}

 public   class  Person : IPerson
{
     public   string  Name {  get ;  set ; }

     public   bool  Believe(IThing thing)
    {
         if (thing  is  OrNotExtensionIsTheBestOf2011)
        {
             var  theBest = thing  as  OrNotExtensionIsTheBestOf2011;
            Console.WriteLine(" 支持 {0} ", theBest.Title);
            Console.WriteLine(" 推荐 {0} ", theBest.Title);
             return   true ;
        }
         throw   new  NotImplementedException();
    }
}

输出:

本文说笑,且莫当真。

滥用扩展方法,切务模仿!

《 c#扩展方法奇思妙用 》系统文章从 2009 年 08 月开始写起,到现在一共有了 23 篇,欢迎阅读: 基础篇: 中文处理 、 string 常用扩展 、 byte 常用扩展 、 Random 扩展 、 Dictionary<TKey, TValue> 扩展 、 WhereIf 扩展 、 IsBetween 通用扩展 、 WhereIf 扩展 、 Distinct 扩展 高级篇: 改进 Scottgu 的 "In" 扩展 、 Aggregate扩展其改进 、 Enumerable.Cast<T>应用 、 对扩展进行分组管理 、 ToString(string format) 扩展 、 WinForm 控件选择器 、 树”通用遍历器 、 Type类扩展 变态篇: 由Fibonacci数列引出“委托扩展”及“递推递归委托” 、 封装 if/else、swith/case及while 、 switch/case 组扩展 、 string 的翻身革命 性能篇 : 扩展方法性能初测 MVC篇: 巧用扩展方法优先级,美化所有页面TextBoxFor文本框

-------------------

思想火花,照亮世界

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于2011 年最佳代码的详细内容...

  阅读:38次