C#3.0之扩展方法

来源:互联网 发布:seo 北京 编辑:程序博客网 时间:2024/04/29 11:22

我们知道在一个类写好之后,在想为这个类加一些新的实例方法,几乎是不可能的,那还得重新编译这个类。而在C#3.0中这个问题得到了很好的解决,使用扩展方法可以轻松的为某个类进行实例方法的扩展。

先看一个例子:

 

 

//注意只有静态类中的方法才能使用扩展方法
public static class Extensions...{
public static void Foo(this string s) ...{   //注意这里的this关键字,是扩展方法的标志
…..
}

}


String s
=“Hello,World”;
s.Foo();  
//等于Extensions.Foo(s);

 

这里字符串s并没有实例方法Foo(),但是我们仍然能成功的编译 ,运行。扩展方法实质就是把对实例方法的调用在编译时改变为对静态类中静态方法的调用。仔细看在Foo()方法里面的this关键字,这个关键字的意思就是告诉编译器这个方法将来有可能作为扩展方法调用。

这里说一下this的使用,我们知道在类的实例方法中我们可以使用this关键字代表对象自身。看一个例子

 

public class Object
{
     
private int x;

      
public void method1()
     
{
           
this.x=0;
     }

}


/*其实在编译器编译的时候会把method1编译成这样*/

public void method1(Object this){....}

/*现在知道我们为什么可以使用this了吧*/

 

编译器不知道有什么实例方法,静态方法等。在编译完成之后就只有全局方法。但是在编译的时候对实例方法和静态方法编译的规则不一样导致编译出来的方法结构也不一样。这也是为什么我们可以在实例方法中调用this而在静态方法中不能调用this的原因.

下面讨论实例方法和静态方法的优先级关系,看一个例子

static class Utilities
    
{
        
public static void F(this Object obj,int i)
        
{
            Console.WriteLine(
"Utilities.F(Object,int)");
        }


        
public static void F(this Object obj,string i)
        
{
            Console.WriteLine(
"Utilities.F(Object,string)");
        }

}

 
class A{}

    
class B
{
        
public void F(int i)
        
{
            Console.WriteLine(
"B.F(int)");
        }

}


    
class C
{
        
public void F(Object obj)
        
{
            Console.WriteLine(
"C.F(Object)");
        }

}

            A a1 
=new A();
            B b 
=new B();
            C c 
=new C();
            a.F(
1);
            a.F(
"hello");
            b.F(
1);
            b.F(
"hello");
            c.F(
1);
            c.F(
"hello");

/*输出结果为:
Utilities.F(Object,int)
Utilities.F(Object,string)
B.F(int)
Utilities.F(Object,string)
C.F(Object)
C.F(Object)
*/

 

我们可以明显看出实例方法的优先级明显高于扩展方法,还有就是namespace就近原则。如果namespace A下有一个扩展方法F,而在namespace A下还有一个命名空间B,在B下同样有一个扩展方法F,那么在调用的时候A下的方法优先级要高。

扩展方法在C#3.0中有很广泛的应用,例如在LINQ中就大量应用了扩展方法。以后说LINQ的时候会提到。

最后要注意扩展方法是编译时技术,和运行时技术反射是不一样的。还有就是扩展方法不能滥用。避免破坏OO的一些好特性。