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";
        }
    }
}
复制代码

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

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

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

posted @   Legolas  阅读(16396)  评论(3编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示