先看下ScottGu對In的擴展:
調用示例1:
調用示例2:
原文地址:New "Orcas" Language Feature: Extension Methods(http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx)
很多介紹擴展方法的也大都使用"In"作為例子,但很少有人再深入想一步。個人感覺這個In擴展的不夠徹底,試看如下代碼:
public static void Example1()
{
bool b1 = 1.In(new int[] { 1, 2, 3, 4, 5 });
bool b2 = "Tom".In(new string[] { "Bob", "Kitty", "Tom" });
}
//ScottGu In擴展
public static bool In(this object o, IEnumerable c)
{
foreach (object i in c)
{
if (i.Equals(o)) return true;
}
return false;
}
每次使用 In 時都要聲明一個數組(或集合),有點麻煩,如果像下面這個樣子調用應該比較簡單一些:
public static void Example2()
{
bool b1 = 1.In(1, 2, 3, 4, 5);
bool b2 = 1.In(1, 2, 3, 4, 5, 5, 7, 8);
bool b3 = "Tom".In("Bob", "Kitty", "Tom");
bool b4 = "Tom".In("Bob", "Kitty", "Tom", "Jim");
}
感覺如何,是否有點類似SQL中的In?
如何擴展的呢,很簡單,這裡使用了 params 這個“方法參數關鍵字”(MSDN中名字),還是看代碼吧!
通過 params 我們不必再顯式聲明數組了,省了不少“筆墨”。
//ScottGu In擴展 改進
public static bool In(this object o, params object[] c)
{
foreach (object i in c)
if (i.Equals(o)) return true;
return false;
}
上面一直是對 object 進行擴展,但存在一個很大的隱患,你的代碼可能會不注意寫成以下的樣子
public static void Example3()
{
string name = "Application1";
string name1 = "Bob";
string name2 = "Kitty";
string name3 = "Tom";
string s = "Tom";
bool b1 = s.In(name1, name2, name3);
bool b2 = s.In(name1, name2, name, 3);//不注意加了個小逗號
}
編譯,照樣運行,出了錯很難查找原因。幸好我們c#有泛型,最後改進一次:
//ScottGu In擴展 改進
public static bool In<T>(this T t, params T[] c)
{
return c.Any(i => i.Equals(t));
}
再編譯,通不過了,報錯如下:
問題解決了。
技術總結:我們使用 params 和 泛型改進了ScottGu的In擴展,使用調用代碼更加簡潔,同時也能減少編程中的誤輸入。
思想總結:網上好多文章都是轉來轉去,沒有自己的想法,其它只要深入想一步,會有很多新發現。