转载

C#扩展方法知多少

什么是扩展方法?回答这个问题之前,先看看我们一般情况下方法的调用。类似这样的通用方法你一定写过:

static void Main(string[] args) {  string strRes = "2013-09-08 14:12:10";  var dRes = GetDateTime(strRes); } //将字符串转换为日期 public static DateTime GetDateTime(string strDate) {  return Convert.ToDateTime(strDate); } //得到非空的字符串 public static string GetNotNullStr(string strRes) {  if (strRes == null)   return string.Empty;  else   return strRes; } 

或者在项目中有一个类似Utils的工具类,里面有多个Helper,例如StringHelper、XmlHelper等等,每个Helper里面有多个static的通用方法,然后调用的时候就是StringHelper.GetNotNullStr("aa");这样。还有一种普通的用法就是new 一个对象,通过对象去调用类里面的非static方法。反正博主刚开始做项目的时候就是这样写的。后来随着工作经验的累积,博主看到了扩展方法的写法,立马就感觉自己原来的写法太Low了。进入正题。

1、.Net内置对象的扩展方法

比如我们要给string对象加一个扩展方法(注意这个方法不能和调用的Main方法放在同一个类中):

public static string GetNotNullStr(this string strRes)         {             if (strRes == null)                 return string.Empty;             else                 return strRes ;         }

然后在Main方法里面调用:

static void Main(string[] args)         {             string strTest = null;             var strRes = strTest.GetNotNullStr();         }

简单介绍:public static string GetNotNullStr(this string strRes)其中this string就表示给string对象添加扩展方法。那么在同一个命名空间下面定义的所有的string类型的变量都可以.GetNotNullStr()这样直接调用。strTest.GetNotNullStr();为什么这样调用不用传参数,是因为strTest就是作为参数传入到方法里面的。你可以试试。使用起来就和.Net framework定义的方法一样:

C#扩展方法知多少

当然除了string,你可以给.Net内置的其他对象加扩展方法,例如给DataGridViewRow的扩展方法:

C#扩展方法知多少
//DataGridViewRow的扩展方法,将当前选中行转换为对应的对象 public static T ToObject<T>(this DataGridViewRow item) where T:class {  var model = item.DataBoundItem as T;  if (model != null)   return model;  var dr = item.DataBoundItem as System.Data.DataRowView;  model = (T)typeof(T).GetConstructor(new System.Type[] { }).Invoke(new object[] { });//反射得到泛型类的实体  PropertyInfo[] pro = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);  Type type = model.GetType();  foreach (PropertyInfo propertyInfo in pro)  {   if (Convert.IsDBNull(dr[propertyInfo.Name]))   {    continue;   }   if (!string.IsNullOrEmpty(Convert.ToString(dr[propertyInfo.Name])))   {    var propertytype = propertyInfo.PropertyType;   }  }  return model; } 
View Code

这样看上去就像在扩展.Net Framework。有没有感觉有点高大上~

2、一般对象的扩展方法

和Framework内置对象一样,自定义的对象也可以增加扩展方法。直接上示例代码:

public class Person     {         public string Name { set; get; }         public int Age { set; get; }     }
//Person的扩展方法,根据年龄判断是否是成年人         public static bool GetBIsChild(this Person oPerson)         {             if (oPerson.Age >= 18)                 return false;             else                 return true;         }

Main方法里面调用:

var oPerson1 = new Person(); oPerson1.Age = 20; var bIsChild = oPerson1.GetBIsChild();

和string扩展方法类似,就不多做解释了。

3、泛型对象的扩展方法

除了上面两种之外,博主发现其实可以定义一个泛型的扩展方法。那么,是不是所有的类型都可以直接使用这个扩展方法了呢?博主就拿昨天序列化的那个方法作为例子吧:

/// <summary> /// 将对象转化为Json字符串 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="instanse">对象本身</param> /// <returns>JSON字符串</returns> public static string ToJsonString<T>(this T instanse) {  try  {   DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(T));   using (MemoryStream ms = new MemoryStream())   {    js.WriteObject(ms, instanse);    ms.Flush();    ms.Seek(0, SeekOrigin.Begin);    StreamReader sr = new StreamReader(ms);    return sr.ReadToEnd();   }  }  catch  {   return String.Empty;  } } 

这个方法是一个通用的序列化的方法,自定义的任何实体,都可以通过以下方式调用:

var oPerson2 = new Person(); var strJson = oPerson2.ToJsonString<Person>();

是不是感觉很方便。

使用扩展方法有几个值得注意的地方:

(1)扩展方法不能和调用的方法放到同一个类中

(2)第一个参数必须要,并且必须是this,这是扩展方法的标识。如果方法里面还要传入其他参数,可以在后面追加参数

(3)扩展方法所在的类必须是静态类

(4)最好保证扩展方法和调用方法在同一个命名空间下

可能你第一次使用这个会觉得很别扭。你也许会说扩展方法和我以前用的static方法无论从代码实现还是算法效率都差不多嘛,是的!确实差不多,但使用多了之后会发现它确实能帮你省去很多代码。

正文到此结束
Loading...