有许多扩展类的方式。继承就是给对象添加功能的好方法。扩展方法是给对象添加功能的另一个选项,在不能使用继承时,也可以使用这个选项(例如类是密封的)。
注意:
扩展方法也可以用于扩展接口。这样,实现该接口的所有类就有了公共功能。扩展方法是静态方法,它是类的一部分,但实际上没有放在类的源代码中。
假设希望用一个方法扩展 string 类型,该方法计算字符串中的单词数。GetWordCount 方法利用 String.Split 方法把字符串分割到字符串数组中,使用 Length 属性计算数组中元素的个数:
ExtensionMethods / Program.cs):
public static class StringExtension
{
public static int GetWordCount(this string s) => s.Split().Length;
}
“
使用 this 关键字和第一个参数来扩展字符串。这个关键字定义了要扩展的类型。
即使扩展方法是静态的,也要使用标准的实例方法语法。注意,这里使用 fox 变量而没有使用类型名来调用 GetWordCount()。
string fox = "the quick brown fox jumped over the lazy dogs down " +
"9876543210 times";
int wordCount = fox.GetWordCount();
Console.WriteLine($"{wordCount} words");
在后台,编译器把它改为调用静态方法:
int wordCount = StringExtension.Getwordcount(fox);
使用实例方法的语法,而不是从代码中直接调用静态方法,会得到一个好得多的语法。这个语法还有一个好处:该方法的实现可以用另一个类取代,而不需要更改代码——只需要运行新的编译器。
编译器如何找到某个类型的扩展方法? this 关键字必须匹配类型的扩展方法,而且需要打开定义扩展方法的静态类所在的名称空间。如果把 StringExtensions 类放在名称空间 Wrox.Extensions 中,则只有用 using 指令开 Wrox.Extensions,编译器才能找到GetWordCount 方法。如果类型还定义了同名的实例方法,扩展方法就永远不会使用。类中已有的任何实例方法都优先。当多个同名的扩展方法扩展相同的类型,打开所有这些类型的名称空间时,编译器会产生一个错误,指出调用是模棱两可的,它不能决定在多个实现代码中选择哪个。然而,如果调用代码在一个名称空间中,这个名称空间就优先。
注意:
语言集成查询(Language Integrated Query,LINQ)利用了许多扩展方法。
-
Love life,love yourself
关注小编不迷路呦~