扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。仅当您使用 using 指令将命名空间显式导入到源代码中之后,扩展方法才位于范围中。

下面的示例演示为 System..::.String 类定义的一个扩展方法。请注意,它是在非嵌套、非泛型静态类内部定义的:

namespace ExtensionMethods

{

    public static class MyExtensions

    {

        public static int WordCount(this String str)

        {

            return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;

        }

    }  

}


可使用以下 using 指令将 WordCount 扩展方法放入范围中:

using ExtensionMethods;

而且,可以在应用程序中使用以下语法对该扩展方法进行调用:

string s = "Hello Extension Methods";

int i = s.WordCount();

在代码中,可以使用实例方法语法调用该扩展方法。但是,编译器生成的中间语言 (IL) 会将代码转换为对静态方法的调用。因此,并未真正违反封装原则。实际上,扩展方法无法访问它们所扩展的类型中的私有变量。

通用准则

通常,建议您只在不得已的情况下才实现扩展方法,并谨慎地实现。只要有可能,必须扩展现有类型的客户端代码都应该通过创建从现有类型派生的新类型来达到这一目的。有关更多信息,请参见继承(C# 编程指南)。

在使用扩展方法来扩展您无法更改其源代码的类型时,您需要承受该类型实现中的更改会导致扩展方法失效的风险。

如果您确实为给定类型实现了扩展方法,请记住以下两点:

如果扩展方法与该类型中定义的方法具有相同的签名,则扩展方法永远不会被调用。

扩展方法被在命名空间级别放入范围中。例如,如果您在同一个名为 Extensions 的命名空间中具有多个包含扩展方法的静态类,则这些扩展方法将全部由 using Extensions; 指令放入范围中。

类库的实施者不应使用扩展方法来避免创建程序集的新版本。如果您要向库中添加重要的新功能,并且您拥有源代码,则应该遵循标准 .NET Framework 程序集版本控制准则。