委托

忽然发现以前的不少观念都不对的,关于编程,关于c#,我认为有须要实现了就成了,结果重要,过程不重要,虽然不少时候你们都讲扩展性、易用性等软件思想,可是在实际应用中,这些基本上都是空话,因此像c#中的委托、类、事件、多线程并无深刻了解,是时候把这块东西深刻了解了解了html

委托编程

一、在C#中,全部的委托都是从System.Delegate类派生的。 c#

二、委托隐含具备sealed属性,即不能用来派生新的类型。安全

三、委托最大的做用就是为类的事件绑定事件处理程序。多线程

四、在经过委托调用函数前,必须先检查委托是否为空(null),若非空,才能调用函数。异步

五、在委托实例中能够封装静态的方法也能够封装实例方法。函数

六、在建立委托实例时,须要传递将要映射的方法或其余委托实例以指明委托将要封装的函数原型(.NET中称为方法签名:signature)。注意,若是映射的是静态方法,传递的参数应该是类名.方法名,若是映射的是实例方法,传递的参数应该是实例名.方法名。spa

七、只有当两个委托实例所映射的方法以及该方法所属的对象都相同时,才认为它们是想等的(从函数地址考虑)。线程

委托是C#中的一种引用类型,相似于C/C++中的函数指针。与函数指针不一样的是,委托是面向对象、类型安全的,并且委托能够引用静态方法和实例方法,而函数指针只能引用静态函数。委托主要用于 .NET Framework 中的事件处理程序和回调函数。 一个委托能够看做一个特殊的类,于是它的定义能够像常规类同样放在一样的位置。与其余类同样,委托必须先定义之后,再实例化。与类不一样的是,实例化的委托没有与之相应的术语(类的实例化称做对象),做为区分咱们将实例化的委托称为委托实例。 指针

函数指针 

  一个函数在编译时被分配给一个入口地址,这个入口地址就称为函数的指针,正如同指针是一个变量的地址同样。

  函数指针的用途不少,最经常使用的用途之一是把指针做为参数传递到其余函数。咱们能够参考下面的例子进一步理解函数指针做为参数的状况:
# include 
   
  int max(int x,int y) 

  { 

      return (x>y?x:y); 

  } 

  int min(int x,int y) 

  { 

     return(x<y?x:y); 
  } 
   
  int sub(int x, int y) 
   
  { 
   
    return(x+y); 
   
  } 

  int minus(int x,int y) 

  {  

    return(x-y); 

  } 

  void test(int (*p)(int,int),int (*q)(int,int),int a,int b) 

  { 

    int Int1,Int2; 

    Int1=(*p)(a,b); 

    Int2=(*q)(a,b); 

    printf("%d,\t%d\n",Int1,Int2); 

  } 

  void main() 

  { 

    test(max,min,10,3); 
     
    test(sub,minus,10,3); 

  } 
客观的讲,使用函数指针做为其参数的函数若是直接调用函数或是直接把调用的函数的函数体放在这个主函数中也能够实现其功能。那么为何还要使用函数指针呢?咱们仔细看一下上面的main()函数就能够发现,
main()函数两次调用了test函数,前一次求出最大最小值,后一次求出两数的和与差。若是咱们test函数不用函数指针,而是采用直接在test函数中调用函数的方法,使用一个test函数还能完成这个功能吗?显然
不行,咱们必须写两个这样的test函数供main()函数调用,虽然大多数代码仍是同样的,仅仅是调用的函数名不同。
上面仅仅是一个简单的例子,实际生活中也许main()函数会频繁的调用test(),而每次的差异仅仅是完成的功能不同,也许第一次调用会要求求出两数的和与差,而下一次会要求求出最大值以及两数之和,第三次呢,
也许是最小值和最大值,……,若是不用函数指针,咱们须要写多少个这样的test()函数?显然,函数指针为咱们的编程提供了灵活性。
另外,有些地方必须使用到函数指针才能完成给定的任务,特别是异步操做的回调和其余须要匿名回调的结构。另外,像线程的执行,事件的处理,若是缺乏了函数指针的支持也是很难完成的。
类型安全
从上面的介绍能够看出,函数指针的提出仍是有其必要的,上面的介绍也同时说明了委托存在的必要性。那么为何C#中不直接用函数指针,而是要使用委托呢?这就涉及到另一个问题:C#是类型安全的语言。
何谓类型安全?这里的类型安全特指内存类型安全,即类型安全代码只访问被受权能够访问的内存位置。 若是代码以任意偏移量访问内存,该偏移量超出了属于该对象的公开字段的内存范围,则它就不是类型安全的代码。
显然指针不属于类型安全代码,这也是为何C#使用指针时必须申明unsafe的缘故。 那么类型不安全代码可能会带来什么不良的后果呢?相信对于安全技术感兴趣的朋友必定十分熟悉缓冲区溢出问题,经过缓冲区溢出攻
击者能够运行非法的程序得到必定的权限从而攻击系统或是直接运行恶意代码危害系统,在UNIX下这是一个十分广泛的问题。那么缓冲区溢出又和函数指针有什么关系呢?事实上,攻击者就是经过缓冲区溢出改变返回地址
的值到恶意代码地址来执行恶意代码的。咱们能够看看下面的代码:
void copy() 
  { 
  char buffer[128]; 
  ........ 
  strcpy (buffer,getenv("HOME"));//HOME为UNIX系统中的HOME环境变量 
  ........ 
  } 
上面的代码中若是HOME环境变量的字符数大于128,就会产生缓冲区溢出,假如这个缓冲区以前有另外一个函数的返回地址,那么这一是地址就有可能覆盖,而覆盖这一地址的字符有可能就是恶意代码的地址,攻击者就有可能
攻击成功了!
  
上面的例子仅仅是指针问题中的一种,除此之外,还可能因为错误的管理地址,将数据写入错误地址,形成程序的崩溃;还可能因为对指针不恰当的赋值操做产生悬浮指针;还可能产生内存越界,内存泄漏等等问题。
  
因而可知,指针不是类型安全的,函数指针固然也不例外,因此C#里面没有使用函数指针,并且不建议使用指针变量。
  
委托
  
前面的说明充分证实了委托存在的必要性,那么咱们再谈谈为何委托是类型安全的。C#中的委托和指针不同,指针不经过MSIL而是直接和内存打交道,这也是指针不安全的缘由所在,固然也是采用指针可以提升程序
运行速度的缘故;委托不与内存打交道,而是把这一工做交给CLR去完成。CLR没法阻止将不安全的代码调用到本机(非托管)代码中或执行恶意操做。然而当代码是类型安全时,CLR的安全性强制机制确保代码不会访问本
机代码,除非它有访问本机代码的权限。 委托派生于基类System.Delegate,不过委托的定义和常规类的定义方法不太同样。委托的定义经过关键字delegate来定义:

public delegate int myDelegate(int x,int y); 
上面的代码定义了一个新委托,它能够封装任何返回为int,带有两个int类型参数的方法。任何一个方法不管是实例方法仍是静态方法,只要他们的签名(参数类型在一个方法中的顺序)和定义的委托是同样的,
均可以把他们封装到委托中去。这种签名方法正是保证委托是类型安全的手段之一。
产生委托实例和产生类实例(对象)差很少,假如咱们有以下的方法: 
public int sub(int x,int y) 
{   
  return(x+y); 
} 
咱们就可使用以下的代码获得一个委托实例:
myDelegate calculatin=new myDelegate(sub); 
接下来咱们就能够直接使用calculation调用sub方法了:
calculation(10,3); 
 下面咱们将用委托重写上面的一个程序来看一下在C#中如何经过委托实现由函数指针实现的功能: 
using System;  
  class MathClass
  { 
      public static int max(int a,int b) 
      { 
          return(a>b?a:b);  
      } 
   
      public static int min(int a,int b) 
      { 
           return(a<b?a:b);  
      } 
   
      public static int sub(int a,int b) 
      { 
         return (a+b); 
       } 
   
      public static int minus(int a,int b)   
      {  
          return (a-b);   
      } 
  } 
   
  class Handler   
  { 
   
      private delegate int Calculation(int a, int b); 
   
      private static Calculation[] myCalculation=new Calculation[2]; 
   
      public static void EventHandler(int i,int a,int b)
    }
            

 博客园里面有不少文章关于委托的,我看到比较好,比较全的是:http://www.cnblogs.com/kirinboy/archive/2009/08/26/intensive-delegate-1.html

相关文章
相关标签/搜索