zoukankan      html  css  js  c++  java
  • C#委托详解(1):什么是委托

    本系列文章将详细探讨C#中的委托,列举其主要的实现方式,并分析其在设计层面和编码层面带来的好处,最后会讨论其安全性和执行效率等。

    什么是委托?

    委托是寻址方法的.NET版本,使用委托可以将方法作为参数进行传递。委托是一种特殊类型的对象,其特殊之处在于委托中包含的只是一个活多个方法的地址,而不是数据。

    委托虽然看起来像是一种类型,但其实定义一个委托,是定义了一个新的类。下面这行代码,定义了一个委托,使用ILDasm.exe查看其生成的IL代码如图所示:

    //定义委托,它定义了可以代表的方法的类型,但其本身却是一个类
     public delegate int methodDelegate(string str);
    032101

    由图中红色框线中可以看出,.NET将委托定义为一个密封类,派生自基类System.MulticastDelegate,并继承了基类的三个方法(稍后讨论这三个)。

    委托与函数指针的区别

    1、安全性:C/C++的函数指针只是提取了函数的地址,并作为一个参数传递它,没有类型安全性,可以把任何函数传递给需要函数指针的地方;而.NET中的委托是类型安全的。

    2、与实例的关联性:在面向对象编程中,几乎没有方法是孤立存在的,而是在调用方法前通常需要与类实例相关联。委托可以获取到类实例中的信息,从而实现与实例的关联。

    3、本质上函数指针是一个指针变量,分配在栈中;委托类型声明的是一个类,实例化为一个对象,分配在堆中。

    4、委托可以指向不同类中具有相同类型返回参数和签名的函数,函数指针则不可以。

    namespace ConsoleApplication1
    {
        //定义委托,它定义了可以代表的方法的类型,但其本身却是一个类
        public delegate void methodDelegate(string str);
        class Program
        {
            static void Main(string[] args)
            {
                Student student = new Student();
                Teacher teacher = new Teacher("王老师");
                methodDelegate methodDelegate1 = new methodDelegate(student.getStudentName);
                methodDelegate1 += teacher.getTeacherName; //可以指向不同类中的方法!
                //methodDelegate1 += teacher.getClassName; 指向签名不符的方法时提示错误!
                methodDelegate1.Invoke("张三");
                Console.ReadLine();
            }
        }
    
        class Student
        {
            private String name = "";
            public Student (String _name)
            {
                this.name = _name ;
            }
            public Student() {}
            public void getStudentName(String _name) 
            {
                if (this.name != "" )
                    Console.WriteLine("Student's name is {0}", this.name);
                else
                    Console.WriteLine("Student's name is {0}", _name);
            }
        }
    
        class Teacher
        {
            private String name;
            public Teacher(String _name)
            {
                this.name = _name;
            }
            public void getTeacherName(String _name)
            {
                if (this.name != "")
                    Console.WriteLine("Teacher's name is {0}", this.name);
                else
                    Console.WriteLine("Teacher's name is {0}", _name);
            }
            public string getClassName() 
            {
                return "Eanlish";
            }
        }
    }

    上述测试代码运行结果如下:

    当指向签名不符的方法时会提示如下错误,证实了委托的安全性。

    本篇结束,下一篇介绍委托的主要实现方式。

  • 相关阅读:
    EJB>依赖注入(dependency injection) 小强斋
    EJB>自定义安全域 小强斋
    EJB>定时服务(Timer Service) 小强斋
    EJB>依赖注入(dependency injection) 小强斋
    EJB>定时服务(Timer Service) 小强斋
    EJB>安全服务的具体开发 小强斋
    EJB>JMS(Java Message Service)和消息驱动bean 小强斋
    EJB>拦截器(Interceptor) 小强斋
    《做最好的员工》第二章:好员工擅长合作
    教你29招,让你在社交,职场上人人对你刮目相看 !
  • 原文地址:https://www.cnblogs.com/Legolas/p/thorough-of-Delegate-1.html
Copyright © 2011-2022 走看看