C# 3.0 扩展方法

来源:互联网 发布:matlab求一个矩阵的和 编辑:程序博客网 时间:2024/05/16 05:14

扩展方法解决问题:以往对已存在的类库进行扩展,可行的方式直接对源代码进行修改或者直接派生。

扩展方法注意事项:

  1. 扩展方法必须被定义在一个静态类中,扩展方法自身必须是一个静态方法;
  2. 扩展方法中的首个参数必须是this,最后紧跟要扩展的类的名称;
  3. 扩展方法可以被对象实例调用,也可以使用静态类名进行静态调用。

扩展方法的使用范围:

实例调用:

namespace ExtensionMethodObjects{    //1,定义一个静态类    public static class ExtensionMethods    {        //2,定义一个静态方法,该方法扩展object对象。        /*         * 扩展方法的的参数部分:第一个参数必须为THIS         * 然后跟随要扩展的类型名称和标识值         */        public static void SayHello(this object obj)        {            Console.WriteLine("扩展方法!");        }    }}
namespace ExtensionMethodObjects{    class Program    {        static void Main(string[] args)        {            //实例化一个object类型的对象            object o = new object();            o.SayHello();        }    }}
扩展方法后,不用对原来的程序集进行任何改动。

静态调用:

namespace InvokeExtensionMethods{    //注意类的可见性级别,必须要在整个应用程序范围可见。     public static  class ExtensionMethods    {         //扩展int类型,为其添加一个反转整数的能力。         public static int ReverseDigits(this int i)         {             char[] digits = i.ToString().ToCharArray();             Array.Reverse(digits);             string newDigits = new string(digits);             return int.Parse(newDigits);         }         //扩展Car类,为其添加一个SpeedDown方法         public static int SpeedDown(this Car car)         {             //这样写将会产生一个编译时错误               //return --Speed;             //正确的方法应该是car.Speed;             return --car.Speed;         }    }}
namespace InvokeExtensionMethods{    class Program    {        static void Main(string[] args)        {            int i = 123456;            //实例方法调用,直接用扩展的类的对象实例来进行调用            Console.WriteLine("实例方法调用,反转后的值为:{0}", i.ReverseDigits());            //静态方法调用,通过调用扩展方法的静态类名再加扩展方法进行调用            Console.WriteLine("静态方法调用,反转后的值为:{0}", ExtensionMethods.ReverseDigits(i));        }    }    //定义一个简单的汽车类    public class Car    {        public int Speed;        public int SpeedUp()        {            return ++Speed;        }    }}

推荐采用实例方法调用,编译器实际上将实例调用编译成静态方法的调用。

扩展方法的地雷区:

  • 扩展方法的名称不能与被扩展的类相同,否者扩展方法不能被调用。

       因为编译时,扩展方法的优先级总是比类型本身中定义的实例方法级别低,其实意思就是类中有一个具有相同签名的扩展方法,编译器总是绑定到该实例方法,当编译器需要调用方法时,首先在该类型的实例方法中寻找匹配的方法。如果未找到任何匹配方法 ,编译器将搜索为该类型定义的任何扩展方法,并且绑定到它找到得第一个扩展方法。  

  • 不能在扩展方法中直接访问扩展方法扩展的类的成员变量,由于扩展方法是静态方法,并不属于类成员中的标准方法,因此不能直接进行访问。可参见上面例子中的静态调用。
  • 如果扩展方法与被扩展的方法具有不同的命名空间,需要在调用扩展方法时引用定义扩展方法的命名空间。
原创粉丝点击