falla.zhang

导航

C# 3.0 扩展方法

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

扩展方法注意事项:

  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;
        }
    }
}

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

扩展方法的地雷区:

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

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

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

posted on 2010-02-23 15:56  falla.zhang  阅读(392)  评论(0编辑  收藏  举报