先看下ScottGu对In的扩展:
调用示例1:
调用示例2:
很多介绍扩展方法的也大都使用"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 ;
}
{
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 " );
}
{
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 ;
}
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 ); // 不注意加了个小逗号
}
{
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));
}
public static bool In < T > ( this T t, params T[] c)
{
return c.Any(i => i.Equals(t));
}
再编译,通不过了,报错如下:
问题解决了。
技术总结:我们使用 params 和 泛型改进了 ScottGu 的 In 扩展,使用调用代码更加简洁,同时也能减少编程中的误输入。