合理使用“.NET扩展方法”来简化代码(例子:空值判断,利用扩展方法实现LINQ操作符ForEach)

 

我们先简单介绍扩展方法的定义,扩展方法是用来在类型定义完成后再继续为其添加新的方法。扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。你只要在静态类的静态方法的参数前加上this,就可以生成这个类的扩展方法。

如果你曾经开发过详细资料修改的窗口或者页面,你一定经常会为空值的判断而感到烦恼。

这时间你被迫在获取值之前先去判断控件的Text值是否为空值,如果为空则输入默认值,如果非空,则进行输入值的类型转换。

User user=new User();

if(tbID.Text!=null&&tbID.Text.Trim()!="")

    user.ID=int.Parse(tbID.Text);

else

     user.ID=-1;

if(tbName.Text!=null&&tbName.Text.Trim()!="")

    user.Name=tbName.Text;

ele

    user.Name="暂无";

............

UserManager.Update(user);

过多的if...else...判断会使代码变成过于复杂,可读性差。此时,使用扩展方法可以代替if(判断式),从而简化代码。只要应用此扩展代码后,以后的空值判断就可以直接使用一个方法去代替,从而摆脱if...else...的困扰。

这时候,你需要创建一个静态类Extension,然后在静态类里面添加一个静态方法GetString,这时候要把第一个参数设置为this string data,现在你已经成功为string类创建了一个扩展方法了。同样,你也可以相同方法为string类创建一个扩展方法GetInt。通过这两个方法你便可以直接在代码中的string对象直接使用这两个方法,而不会再受if...else...的困扰。

public static class Extension

{

     public static string GetString(this string data )

     {

          if(data!=null&&data.Trim()!="")

               return data; 

          else

               return “暂无”;

     }

     public static int GetInt(this string data )

     {

            if(data!=null&&data.Trim()!="")

                return int.Parse(data);

            else

                return -1;

     }

}

现在,你可以直接在String类里面直接使用GetString(),GetInt()这两个扩展方法了

User user=new User();

user.ID=tbID.Text.GetInt();

user.Name=tbName.Text.GetString();

.............

UserManager.Update(user);

如果你对LINQ的结构有了一定的了解,那么你就应该理解LINQ的表达式正是使用IEnumerable或者IEnumerable<T>的扩展方法生成的,多 个LINQ的操作符都可以利用代码进行扩展,你可以按需要写下实用性更高的操作符。在介绍LINQ扩展方法前,先介绍一下LINQ里面常用的委托。

delegate void Action<T>(T obj)

delegate TOutput Converter<TInput,TOutput>(TInput input);

delegate Boolean Predicate<T>(T object);

delegate void Func<TResult>();

delegate void Func<T,TResult>();

在介绍如何开发LINQ的自定表达式前,先为大家介绍一下LINQ里面Where操作符的实现方式。

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source ,Func<TSource,Boolean> predicate)

{

       foreach(TSource element in source)

       {

            if(predicate(element))

               yield return element;

       }

}

这样每个IEnumerable<T>都可以使用Where操作符,在你对扩展已经有了一定的了解后,你也可以尝试为LINQ建立更多适用的操作符了。在很多LINQ数据查询时,你都会用到foreach去对查询结果进行操作,每次都使用foreach可能令你感到厌烦。

例如:下面是你最常用方法

IEnumerable<Book>  books=from x in BookList

                                                     select x;

foreach(Book book in books)

{

       Console.WriteLine("Book Name is"+book.Name);

       Console.WriteLine("Book Author is"+book.Author);

       ..........

}

现在你可以尝试用扩展方法为IEnumerable<T>设置一个ForEach表达式

public static void ForEach<T>(this IEnumerable<T> source ,Action<T> func)

{

     foreach(var item in source)

          func(item);

}

通过一个这样简简单单的扩展方法,你就可以直接在LINQ表达式中实现ForEach

DataBase.Books.Where(x=>x.Price>30)

                        .ForEach(x=>{

                                                    Console.WriteLine(“Book Name is”+x.Name);

                                                    Console.WriteLine(“Book Author is" +x.Author);

                                     } );

在LINQ里面,扩展方法随处可见,深入了解扩展方法,可以让你按需要而为系统可发更适用的方法,从而简化代码,赶快动手,设置一些合适自己使用的扩展方法吧!对.NET开发有兴趣的朋友请加入博客园讨论小组“.NET高级编程” 一起探讨!

 

对 JAVA 开发有兴趣的朋友欢迎加入QQ群:174850571 共同探讨!
对 .NET  开发有兴趣的朋友欢迎加入QQ群:162338858 共同探讨 !

 

.NET基础篇

以异步的方式操作TCP/IP套接字——以异步方式实现简单的聊天室
合理使用“.NET扩展方法”来简化代码(例子:空值判断,利用扩展方法实现LINQ操作符ForEach)
分部类和分部方法
反射的奥妙
利用泛型与反射更新实体(ADO.NET Entity Framework)

 

作者:风尘浪子
http://www.cnblogs.com/leslies2/archive/2011/01/28/1939883.html

原创作品,转载时请注明作者及出处






posted on 2011-01-28 11:05  风尘浪子  阅读(5404)  评论(12编辑  收藏  举报

导航