扩展方法,就是对存在的方法的添加或者称作补充,他不属于重载,不需要重新创建派生类型、重新编译等其他修改原有类型。扩展方法也是一种方法,只不过是一种特殊的方法,只能是静态类型的方法。
扩展方法的规则:
1、定义包含扩展方法的静态类,此类必须对客户端代码可见。
2、将扩展方法实现为静态方法,并且使其可见性至少与所在类的可见性相同。
3、此方法的第一个参数指定方法所操作的类型;此参数前面必须加上this修饰符。
4、在调用代码中,添加 using
指令,用于指定包含扩展方法类的命名空间。
5、和调用类型的实例方法那样调用这些方法。
6、第一个this参数不能使用out等关键字
下面我们来尝试一下:
//定义一个扩展类
public static class StringExtention
{
public static string StrEquals(this string strA, string strB)
{
return strA == strB ? strB : strA;
}
}
然后我们来调用它:
static void Main(string[] args)
{
string a = "a";
string c = a.StrEquals("b");
Console.WriteLine(c);
Console.Read();
}
关于调用重名问题:
//定义一个扩展类
public static class StringExtention
{
public static string Equals(this string strA, string strB)
{
return strA == strB ? strB : strA;
}
}
由于版本的迭代不排除有些重名的扩展方法或者方法,所以有些时候扩展方法为了区分其他方法,我们也会给这个需要扩展的方法叫上这个名字,这个时候我们这里调用的时候a.Equals("b")的时候会报错,不会调用这个扩展的方法,但是我们现在想要调用这个扩展方法怎么办呢?
我们回看前面的扩展方法的规则里面说到“和调用类型的实例方法那样调用这些方法”,所以,解决方案如下:
string d = StringExtention.Equals(a,"b");
关于调用顺序问题:
我们调用这个Equals的时候,发现这个扩展方法放在这个被扩展的方法的后面,但是调用的时候是不会被调用到的,所以扩展方法的优先级是低于这个被扩展的方法的。
关于编译器是如何找到扩展方法的:
首先我们调用这个方法的时候,编译器第一个找的地方就是实例方法,如果没有找到这个实例方法,编译器就会自动找扩展方法。通过反编译器就可以查看到一个重要的信息:[assembly:Extention]