C#扩展方法详解

在之前的文章中,讨论了构造函数和运算符重载的方法。扩展方法是C#3.0中引入的一个特性。C#中的扩展方法用于扩展一个类的功能,而不需要修改原有类型的声明。

扩展方法是一个静态类中的静态方法,其中第一个参数应用了this修饰符。第一个参数的类型将是被扩展的类型。

扩展方法的语法

以下是一个扩展方法的示例代码,稍后将讨论其使用方法:

public static class StringExtension { public static string CapitalizeFirstCharacter(this string strPara) { StringBuilder capitalizedString = new StringBuilder(); string[] allWords = strPara.Split(null); foreach (string item in allWords) { capitalizedString.Append(Regex.Replace(item, @"^\w", m => m.Value.ToUpper()) + ""); } return capitalizedString.ToString(); } }

扩展方法的使用

正如已经讨论的,扩展方法用于扩展现有类的功能。为String类创建了一个扩展方法,用于获取字符串中每个单词的首字母大写。

string myName = "my name is vikram"; string firstCharacterUpper = myName.CapitalizeFirstCharacter(); Console.WriteLine(firstCharacterUpper); Console.ReadKey();

以上代码的输出结果如下:

假设如果没有扩展方法的存在,那么需要创建一个静态类,并在该类中定义一个静态方法。在这种情况下,CapitalizeFirstCharacter方法将被定义如下:

public static class StringExtension { public static string CapitalizeFirstCharacter(string strPara) { StringBuilder capitalizedString = new StringBuilder(); string[] allWords = strPara.Split(null); foreach (string item in allWords) { capitalizedString.Append(Regex.Replace(item, @"^\w", m => m.Value.ToUpper()) + ""); } return capitalizedString.ToString(); } }

可以像下面这样使用这个方法:

string firstCharacterUpper = StringExtension.CapitalizeFirstCharacter(myName); Console.WriteLine(firstCharacterUpper); Console.ReadKey();

这种方法没有问题,但从程序员的角度来看,这不是理想的。传统方法的第一个问题是,开发者不知道是否存在一个静态类中的方法可以帮助实现所需的功能。第二个问题是,静态类和静态方法会分散程序员对操作的注意力。

但是,如果看扩展方法的使用第一种方法,可以看到Visual Studio的智能感知提供了在string类上工作时看到函数的便利,如下图所示。正如所看到的,扩展方法旁边有一个特殊的符号,即一个向下的箭头,工具提示确实显示它是一个扩展方法。

现在在使用扩展方法时,非常确定想要在string类上执行的操作。

编译器如何处理扩展方法

当编译器看到以下代码行时:

string firstCharacterUpper = myName.CapitalizeFirstCharacter();

编译器首先检查String类或任何基类是否提供了一个名为CapitalizeFirstCharacter()的实例方法,该方法接受一个类型为string的参数。如果存在现有的方法,则编译器发出调用它的代码。如果没有找到匹配的实例,则编译器将查看任何定义了名为CapitalizeFirstCharacter()的静态方法的静态类,这些方法的第一个参数的类型与用于调用方法的表达式的类型匹配,即例子中的string。

使用扩展方法的规则

需要导入定义了静态类的命名空间,其中包含扩展方法。假设在StringExtension类中定义了CapitalizeFirstCharacter方法,该类又定义在命名空间下。在这种情况下,需要在任何想要使用CapitalizeFirstCharacter方法的地方使用using关键字包含命名空间。

C#仅支持扩展方法,不支持扩展属性、扩展事件、扩展运算符。扩展方法必须在非泛型和静态类中声明。C#编译器仅查找在文件范围定义的静态类中定义的扩展方法。换句话说,如果在某个类中定义了一个静态类,然后定义扩展方法,在这种情况下,将得到一个编译时错误,如下所示。

多个静态类可以实现相同的扩展方法。在这种情况下,将得到一个编译时错误,如下所示。

克服这个错误的唯一方法是更改源代码。如果在C#中用一些扩展方法扩展了一个类型,那么所有派生类型也有资格使用这个方法。假设扩展了System.Object,那么所有类型都将具有该特定的扩展方法。这就是为什么应该非常谨慎地使用这个特性。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485