博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

扩展方法

Posted on 2011-01-28 13:01  steve.z  阅读(236)  评论(0编辑  收藏  举报

扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。

  

最常见的扩展方法是 LINQ 标准查询运算符,它们向现有的 System.Collections..::.IEnumerable System.Collections.Generic..::.IEnumerable<(Of <(T>)>) 类型添加了查询功能。

 

扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。

 

它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。

 

仅当您使用 using 指令将命名空间显式导入到源代码中之后,扩展方法才位于范围中。
 
扩展方法是在非嵌套、非泛型的静态类内部定义的。
 
扩展方法无法访问它们所扩展的类型中的私有变量。
 
与接口或类方法中具有相同名称和签名的扩展方法永远不会被调用。
 
如果扩展方法与该类型中定义的方法具有相同的签名,则扩展方法永远不会被调用。
 
扩展方法被在命名空间级别放入范围中。例如,如果您在同一个名为 Extensions 的命名空间中具有多个包含扩展方法的静态类,则这些扩展方法将全部由 using Extensions; 指令放入范围中。
 
扩展方法可以被继承,如果为object类添加了扩展方法,则所有类都拥有了该方法。
 
类库的实施者不应使用扩展方法来避免创建程序集的新版本。如果您要向库中添加重要的新功能,并且您拥有源代码,则应该遵循标准 .NET Framework 程序集版本控制准则。有关更多信息,请参见程序集版本控制。

 

 

  通常,建议您只在不得已的情况下才实现扩展方法,并谨慎地实现。只要有可能,必须扩展现有类型的客户端代码都应该通过创建从现有类型派生的新类型来达到这一目的。在使用扩展方法来扩展您无法更改其源代码的类型时,您需要承受该类型实现中的更改会导致扩展方法失效的风险。(例如,在原有类中添加了与扩展方法重名的实例方法)   

 

 

定义和调用扩展方法

1.   定义一个静态以包含扩展方法。

该类必须对客户端代码可见。有关可访问性规则的更多信息,请参见访问修饰符(C# 编程指南)

2.   将该扩展方法实现为静态方法,并使其至少具有与包含类相同的可见性。

3.   该方法的第一个参数指定方法所操作的类型;该参数必须以 this 修饰符开头。

4.   在调用代码中,添加一条 using 指令以指定包含扩展方法类的命名空间

5.   按照与调用类型上的实例方法一样的方式调用扩展方法。

请注意,第一个参数不是由调用代码指定的,因为它表示正应用运算符的类型,并且编译器已经知道对象的类型。您只需通过 n 为这两个形参提供实参。

  

示例:

 下面的示例在 MyExtensions.StringExtension 类中实现了一个名为 WordCount 的扩展方法。该方法对 String 类进行操作,而该类被指定为第一个方法参数。MyExtensions 命名空间被导入到应用程序命名空间中,并且该方法是在 Main 方法内调用的。 

 

代码
1 using System.Linq;
2  using System.Text;
3  using System;
4
5  namespace CustomExtensions
6 {
7 //Extension methods must be defined in a static class
8   public static class StringExtension
9 {
10 // This is the extension method.
11 // The first parameter takes the "this" modifier
12 // and specifies the type for which the method is defined.
13   public static int WordCount(this String str)
14 {
15 return str.Split(new char[] {' ', '.','?'}, StringSplitOptions.RemoveEmptyEntries).Length;
16 }
17 }
18 }
19  namespace Extension_Methods_Simple
20 {
21 //Import the extension method namespace.
22   using CustomExtensions;
23 class Program
24 {
25 static void Main(string[] args)
26 {
27 string s = "The quick brown fox jumped over the lazy dog.";
28 // Call the method as if it were an
29 // instance method on the type. Note that the first
30 // parameter is not specified by the calling code.
31   int i = s.WordCount();
32 System.Console.WriteLine("Word count of s is {0}", i);
33 }
34 }
35 }