扩展函数

扩展函数

  以下内容大部分来源于:http://www.cnblogs.com/sunrack/articles/1073759.html

             http://blog.csdn.net/hu8hong9/article/details/1856026

  1、在什么情况下使用

    使用扩展函数,可以为无法修改源代码的对象添加新的方法,或者强制让对象支持某些方法,这些方法看起来就是对象本来就有的功能。当我们在对类A的进行操作时,发现类A中没有某些方法,我们又不能对类A直接修改,但是我们又要用到该方法时,可以用扩展函数的功能新建一个类,并且创建要使用的方法。

   2、使用方法:

    声明扩展函数:扩展函数使用特定的关键字this作为修饰符应用于函数的第一个参数来声明。扩展函数只能声明在static的类中

    导入扩展函数:扩展函数通过using-namespace-directives 导入。另外导入的有,该namespace所包含的类型,using-namespace-directive 导入所有的扩展函数在该namespace中的所有static类。被导入的扩展函数有效地作为在某些类型上的额外函数,这是通过它们的第一个关键字以及比常规的实例函数更低的优先级所给与的。

    扩展函数的调用:如果正常的调用过程中没有发现适用的实例函数(尤其如果对此调用的候选函数为空的情况下),编译器将做出尝试将构造过程作为扩展函数来调用。

  3、限制条件

    1、必须在static class 中定义,所以必须使用static修饰
     2、需要在(只需要在)第一个参数前面使用this修饰
     3、扩展函数可以通过对象实例调用,也可以使用定义该函数的静态类直接调用

  4、简单的例子

    新建一个类:

复制代码
public static class E {
        public static string F(this object obj, int i)//扩展函数
        {
            return "E:"+i.ToString();
        }

        public static string F(this object obj, string s)
        {
            return "E:" + s;
        }
    }
    class A {//类A中没有方法
    }
    class B {
        public string F(int i)
        {
            return "B:" + i.ToString();
        }
    }
    class C {
        public string F(object obj)
        {
            return "C:" + obj.ToString();
        }
    }
复制代码


添加相应函数如下:

复制代码
//B的函数优先于前面的扩展函数,并且C的函数优先于所有的扩展函数。
        protected void Button1_Click(object sender, EventArgs e)
        {
            A a = new A();             //A中没有F()函数,将调用扩展函数
            Label1.Text=a.F(1);                         // E.F(object, int)
            Label1.Text +="<br/>"+ a.F("hello");     // E.F(object, string)
            
            B b = new B();             //B中有F(int),则调用此,没有对string的操作,调用扩展函数。
            Label1.Text += "<br/>" + b.F(1);              // B.F(int)
            Label1.Text += "<br/>" + b.F("hello");     // E.F(object, string)

            C c=new C();
            Label1.Text += "<br/>" + c.F(1);              // C.F(object)
            Label1.Text += "<br/>" + c.F("hello");     // C.F(object)
        }
复制代码

 运行结果如下:

  5、使用范围

    扩展函数本质上是在被扩展的对象实例上可以调用的静态函数,不是继承,所以不同于普通的成员函数,扩展函数不能直接访问被扩展对象的成员。只能通过该对象的实例来访问。

  6、扩展接口类型

在接口中必须给出方法的实现

//  Define a normal CLR interface in C#.
interface IBasicMath
{
int Add( int x,  int y);
}
//  Implementation of IBasicMath.
class MyCalc : IBasicMath
{
public  int Add( int x,  int y)
{
return x + y;
}
}

但是,如果只是如下扩展,将会发生错误

static  class MathExtensions
{
//  Extend IBasicMath with subtraction method?
public  static  int Subtract( this IBasicMath itf,
int x,  int y);
}

必须给出函数的实现

static  class MathExtensions
{
//  Extend IBasicMath this method and this
//  implementation.
public  static  int Subtract( this IBasicMath itf,
int x,  int y)
{
return x - y;
}
}

调用
static  void Main( string[] args)
{
Console.WriteLine( " ***** Extending an interface *****\n ");
//  Call IBasicMath members from MyCalc object.
MyCalc c =  new MyCalc();
Console.WriteLine( " 1 + 2 = {0} ", c.Add( 12));
Console.WriteLine( " 1 - 2 = {0} ", c.Subtract( 12));
//  Can also cast into IBasicMath to invoke extension.
Console.WriteLine( " 30 - 9 = {0} ",
((IBasicMath)c).Subtract( 309));
//  This would NOT work!
//  IBasicMath itfBM = new IBasicMath();
//  itfBM.Subtract(10, 10);
Console.ReadLine();
}

扩展接口后,显然不能直接在接口上调用这些扩展函数,只能理解为,所有继承该接口的对象新增加了这些扩展函数功能,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值