using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CommonSD { public static class MyExtensions { public static void DisplayDefiningAssembly(this object obj) // { //Console.WriteLine("{0} lives here:=> {1}\n", obj.GetType().Name, Assembly.GetAssembly(obj.GetType()).GetName().Name); } public static int ReverseDigits(this int i) { // 把int翻譯為string然后獲取所有字符 char[] digits = i.ToString().ToCharArray(); // 現在反轉數組中的項 Array.Reverse(digits); // 放回string string newDigits = new string(digits); // 最后以int返回修改后的字符串 return int.Parse(newDigits); } public static int ToInt(this string value) { return int.Parse(value); } } }
什么是擴展方法?回答這個問題之前,先看看我們一般情況下方法的調用。類似這樣的通用方法你一定寫過:
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內置對象的擴展方法
.Net內部也有很多定義的擴展方法,例如我們Linq常用的Where(x=>x==true)、Select()等等。當你轉到定義的時候你很容易看出來:public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)。當然我們也可以給.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定義的方法一樣:

當然除了string,你可以給.Net內置的其他對象加擴展方法,例如給DataGridViewRow的擴展方法:
//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;
}
這樣看上去就像在擴展.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、泛型對象的擴展方法
除了上面兩種之外,博主發現其實可以定義一個泛型的擴展方法。那么,是不是所有的類型都可以直接使用這個擴展方法了呢?為了保持程序的嚴謹,下面的方法可能沒有實際意義,當開發中博主覺得可能存在這種場景:
public static class DataContractExtensions
{
//測試方法
public static T Test<T>(this T instance) where T : Test2
{
T Res = default(T);
try
{
Res.AttrTest = instance.AttrTest.Substring(0,2);
//其他復雜邏輯...
}
catch
{ }
return Res;
}
}
public class Test2
{
public string AttrTest { set; get; }
}
使用擴展方法有幾個值得注意的地方:
(1)擴展方法不能和調用的方法放到同一個類中
(2)第一個參數必須要,並且必須是this,這是擴展方法的標識。如果方法里面還要傳入其他參數,可以在后面追加參數
(3)擴展方法所在的類必須是靜態類
(4)最好保證擴展方法和調用方法在同一個命名空間下

