C# 扩展方法

顾名思义,扩展方法是附加方法。扩展方法使您可以注入其他方法,而无需修改,派生或重新编译原始类,结构或接口。可以将扩展方法添加到您自己的自定义类,.NET Framework类或第三方类或接口中。

扩展方法的定义

扩展方法是C# 3.0 中新增特性,可在不修改源类代码情况,通过ADD File 模式对源代码功能扩展。

扩展方法要求如下:

  • 扩展方法需包含在 static 修饰类中。

  • 扩展实现需是静态形式。

  • 扩展方法第一个参数 前缀为 this , 表示需要扩展类对象,从第二个参数开始,为扩展方法参数列表。

在以下示例中,IsGreaterThan()是int类型的扩展方法,如果int变量的值大于提供的整数参数,则返回true。

int i = 10;

bool result = i.IsGreaterThan(100); //返回FALSE

IsGreaterThan ()方法不是 int 数据类型的方法(Int32 struct)。它是程序员为 int 数据类型编写的扩展方法。通过包含定义 IsGreaterThan ()扩展的命名空间,IsGreaterThan ()扩展方法将在整个应用程序中可用。

 扩展方法在Visual Studio的intellisense中具有特殊符号,因此您可以轻松区分类方法和扩展方法。

扩展方法图标
Visual Studio智能感知中的扩展方法符号

编写扩展方法

现在让我们看看如何编写扩展方法。

LINQ建立在对IEnumerable和IQeryable类型进行操作的扩展方法上。

扩展方法实际上是在静态类中定义的一种特殊的静态方法。要定义扩展方法,首先,定义一个静态类。

例如,在以下示例中,我们在 ExtensionMethods 命名空间下创建了一个类 IntExtensions。IntExtensions 类将包含适用于int数据类型的所有扩展方法。(您可以为命名空间和类使用任何名称。)

namespace ExtensionMethods
{
    public static class IntExtensions
    {

    }
}

现在,将静态方法定义为扩展方法,其中扩展方法的第一个参数指定了适用扩展方法的类型。我们将在int类型上使用此扩展方法。因此,必须在第一个参数 int 之前加上this 修饰符。

例如,IsGreaterThan()方法对int进行操作,因此第一个参数为this int i。

namespace ExtensionMethods
{
    public static class IntExtensions
     {
        public static bool IsGreaterThan(this int i, int value)
        {
            return i > value;
        }
    }
}

现在,您可以将 ExtensionMethods 命名空间包含在任何希望使用此扩展方法的地方。

使用扩展方法

using ExtensionMethods;

class Program
{
    static void Main(string[] args)
    {
        int i = 10;

        bool result = i.IsGreaterThan(100); 

        Console.WriteLine(result);
    }
}
输出:
false
常规静态方法和扩展方法之间的唯一区别是,扩展方法的第一个参数指定其将要对运算符进行操作的类型,其后跟 this 关键字。

扩展方法的原则总结

  1. C#只支持扩展方法,不支持扩展属性、扩展事件、扩展操作符等。

  2. 扩展方法(第一个参数前面是this的方法)必须在非泛型的静态类中声明,扩展方法必须有一个参数,而且只有第一个参数使用this标记。

  3. C#编译器查找静态类中的扩展方法时,要求这些静态类本身必须具有文件作用域。

  4. C#编译要求“导入”扩展方法。(静态方法可以任意命名,C#编译器在寻找方法时,需要花费时间进行查找,需要检查文件作用域中的所有的静态类,并扫描它们的所有静态方法来查找一个匹配)

  5. 多个静态类可以定义相同的扩展方法。
    用一个扩展方法扩展一个类型时,同时也扩展了派生类型。

扩展方法声明

  • 必须在一个非嵌套的、非泛型的静态类中(所以必须是一个静态方法)

  • 至少有一个参数。

  • 第一个参数必须附加this关键字做前缀。

  • 第一个参数不能有其他任何修饰符(如ref或out)。

  • 第一个参数的类型不能是指针类型。

要记住的要点

  • 扩展方法是最初不包含在类中的其他自定义方法。

  • 扩展方法可以添加到自定义,.NET Framework或第三方类,结构或接口。

  • 扩展方法的第一个参数必须是适用扩展方法的类型,其后跟this关键字。

  • 通过包含扩展方法的名称空间,可以在应用程序中的任何位置使用扩展方法。