许多实际的扩展可以通过扩展方法来实现,并非所有实际的扩展都有可以扩展的类型。对于某些场景,简单的静态方法比较适合。为了更容易调用这些方法,可以使用 using static 声明除去类名。.
例如,如果打开了 System.Console
using static System.Console;
可以把下面的代码
Console.WriteLine("Hello World!");
改为
WriteLine("Hello World!");
在使用此声明之后,就可以使用类 Console 的所有静态成员,如 WriteLine、Write、ReadLine、Read、Beep 等,而不需要编写 Console 类。只需要确保在打开其他类的静态成员时不要陷入冲突,或者在使用静态方法时不要使用基类的方法。
下面看一个实际的例子。高阶函数以函数作为参数,或者返回一个函数,或者返回两个函数。在处理函数时,可以将两个函数合并到一个函数中。
为此可以使用Compose 方法,如下面的代码片段所示:
public static class FunctionalExtensions{//...public static Func<T1, TResult> Compose<T1, T2, TResult>(Func<T1, T2> fl, Func<T2, TResult> f2) =>a => f2(f1(a));}
要使用 Compose 方法,首先创建两个委托 f1 和 f2,在输入中添加 1 或 2。这些委托会与 Compose 方法相结合。由于 usingstatic 声明打开了类 FunctionalExtensions 的静态成员,所以可以不使用类名来调用 Compose 方法。在使用 Compose 方法创建 f3之后,就调用 f3 方法:
using System;using static System.Console;using static UsingStatic.FunctionalExtensions;namespace UsingStatic{class Program{static void Main(){//...Func<int, int> f1 = x => x + 1;Func<int, int> f2 = x => x + 2;Func<int, int> f3 = Compose(f1, f2);var xl = f3(39);WriteLine(x1);//...}}}
写入控制台的结果当然是 42。
声明 Compose 方法时,参数类型可以在输入和输出之间有所不同。在下面的代码片段中,传递给 Compose 方法的第一个方法接收一个字符串,并返回 Person 对象;第二个方法接收 Person 并返回一个字符串。如果编译器不能从变量和返回类型中识别参数类型,就必须指定具体的委托类型,方法是接收字符串并返回一个 Person。只有变量名,并不能帮助编译器确定它的类型。通过传递给 Compose 方法的第二个方法,显然,输入的类型与第一个方法返回的类型相同,因此不需要指定类型。在调用Compose 方法之后,变量 greetPerson 是两个输入方法的组合:
var greetPerson = Compose(new Func<string, Person>(name => new Person(name)),person => $"Hello, {person.FirstName}");WriteLine(greetPerson("Mario Andretti"));
在WriteLine 方法中使用字符串 Mario Andretti 调用greetPerson 方法将字符串 Hello,Mario 写入控制台。
