你的位置:首页 > ASP.net教程

[ASP.net教程]关于扩展方法,需要留意的原则和规则


  • C#只支持扩展方法,不支持扩展属性、扩展事件、扩展操作符
  • 扩展方法必须在非泛型的静态类中声明,而且扩展方法至少要有一个参数,而且只有第一个参数能用this关键字标记
  • C#在静态类中查找方法时,要求静态类本身必须具有文件作用域,即扩展方法必须在顶级静态类中定义,而不能在嵌套的静态的类中的定义
  • 由于静态类可以取任何名字,所以C#编译器要花一定的时间来寻找扩展方法,它必须检查文件作用域中的所有静态类,并扫描他们的所有静态方法来查找一个匹配;

        我可不可以这样理解,性能只是在编译时有损失,编译之后就和普通的静态方法调用一样了,没有任何区别,之所以能得出这个结论是因为通过比较如下的两种调用方式和对应的IL代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Extention{  class Program  {    static void Main(string[] args)    {      var dt = DateTime.Now;      var dtString = dt.DT();      var dtString1 = Extention.Extention1.DT(dt);      var dtString2 = Extention.Extention1.DT1(dt);      Console.ReadLine();    }  }  public static class Extention1  {    public static string DT(this DateTime dt)    {      return dt.ToString();    }    public static string DT1(DateTime dt)    {      return dt.ToString();    }  }}

 Main函数中对DT的三种调用生成的IL代码如下:

 


  • 多个静态类可以定义相同的扩展方法,如果编译器检测到存在两个或多个扩展方法,就会提示调用不明确,此时需要调用静态方法语法的方式来代替实例方法语法
  • 用一个扩展方法扩展一个类型时,同时也扩展了派生类,所以不要将Object作为扩展方法的第一个参数,否则这个方法在所有表达式上都能调用
  • 扩展方法存在版本控制问题(为同一个类型定义两个相同的扩展方法,后来者会把前面的覆盖掉,导致行为不一致)