C#3.0中增加了许多新特性.其中.扩展方法允许我们在不修改原有代码的基础上扩展类/接口的功能.有技巧的运用该特性.能写出有效率/易维护/美观的代码.
增强现有接口
C#2.0提供了许多泛型与容器的接口和类.最常见的如IComparable<T>常常需要新建一个Comparable来进行排序比较等等..但其默认只有一个CompareTo方法.在以前.我们只能手动添加.并且很难复用代码.如今.利用扩展方法.可以很方便地扩展该接口.
public
static
class
Comparable
{
public
static
bool
LessThan
<
T
>
(
this
T left, T right)
where
T : IComparable
<
T
>
{
return
left.CompareTo(right)
<
0
;
}
public
static
bool
GreaterThan
<
T
>
(
this
T left, T right)
where
T : IComparable
<
T
>
{
return
left.CompareTo(right)
>
0
;
}
public
static
bool
LessThanEqual
<
T
>
(
this
T left, T right)
where
T : IComparable
<
T
>
{
return
left.CompareTo(right)
<=
0
;
}
public
static
bool
GreaterThanEqual
<
T
>
(
this
T left, T right)
where
T : IComparable
<
T
>
{
return
left.CompareTo(right)
>=
0
;
}
}
如此一来.只要我们引用该类的命名空间.便可扩展的使用扩展方法.例如:
public
class
Student : IComparable
<
Student
>
{
public
int
CompareTo(Student other)
{
return
StuNo.CompareTo(other.StuNo);
}
public
int
StuNo {
get
;
set
; }
public
string
StuName {
get
;
set
; }
}
Student a
=
new
Student() { StuNo
=
1
, StuName
=
"
a
"
};
Student b
=
new
Student() { StuNo
=
2
, StuName
=
"
b
"
};
Console.WriteLine(a.LessThan(b));
注意!若是某个类需要定义一个方法,而这个类所实现的接口中也给出了同名的扩展方法,那么也许会导致一些意料之外的行为.根据方法的解析规则,类中的方法将会被优先调用,不过这个解释发生在编译器.若是通过接口来调用方法,则调用方法上的扩展方法,而非类的方法.
增强现有类型
除了能扩展接口.同样.扩展方法对类也有强大的支持.C#3.0中提供了许多扩展方法.特别是对于泛型容器的支持特别丰富.有时候.我们可能也会根据需要增加自己的扩展方法.例如.有一个学生的容器.可能需要增加对于学生的特别查询.如最近旷课最多的学生.请假最多的学生等.以前.我们可以自己写一个学生的列表类StudentList继承List<Student>.但现在我们可以直接扩展List<Student>.前者相比较后者,存在着更多的限制.扩展方法是用IEnumerable<Student>作为参数,而派生类基于List<Student>,即强制要求使用一种特定的存储模型.因此.前者的做法无法与一系列的迭代方法组合使用.使方法的使用者受到不必要的约束.后者的使用更为灵活.
扩展方法的建议
虽然扩展方法给我们带来很大的便利.但这不总是设计上的首选.只有在重用项目扩展功能.最好不要在不同的命名空间中声明同名的扩展方法.这样会增加后期的维护成本.扩展方法尽量不要重载.更应该使用与功能更贴切的签名.