C#之委托

2023-05-16

委托:顾名思义,让别人帮你办件事。委托是C#实现回调函数的一种机制。可能有人会问了,回调函数是个啥???

举个例子:我现在是一家公司的老板,公司现在在招聘.NET工程师,我们有一个小姐姐专门负责接受求职者投递的简历,我就告诉这个小姐姐,一旦收到新的简历就转发给我一份。

这个例子里小姐姐要做的工作:给我转发一份简历(回调函数里的操作),就是一个回调函数的作用。一旦有了满足条件(收到了新的简历),小姐姐就会转发给我(触发回调函数

用来代码来看看是怎么实现的:

1.定义一个委托:


   // 定义委托,这个委托需要获取一个int型参数,返回void
        internal delegate void Feedback(int value);  

 

2.定义回调方法:这里定义了两个方法,一个静态,一个实例。正好看看调用方式的不同。注意:定义的回调方法签名必须和委托对象一致(这里都是int 类型参数,没有返回值。这么说也不全对,涉及到协变逆变。这里就不解释这俩了),这是因为将方法绑定到委托时,编译器会检测他们的兼容性。不符合的话回报编译错误。就比如有一个方法要传入String类型,我们给它传递了一个int类型一样。

这里为了方便演示就只把数字打印在了控制台。


 /// <summary>
        /// 静态回调方法
        /// </summary>
        /// <param name="value"></param>
        private static void FeedbackToConsole(int value)
        {
            // 依次打印数字
            Console.WriteLine("Item=" + value);
        }
        /// <summary>
        /// 实例回调方法
        /// </summary>
        /// <param name="value"></param>
        private void InstanceFeedbackToConsole(int value)
        {
            Console.WriteLine("Item=" + value);
        }  

 

3.编写一个方法来触发回调函数:有三个参数:前两个做循环使用,后一个接收定义的委托对象。内部代码循环调用回调方法 fb(val)的写法,其实就是相当于要调用的函数。例:


FeedbackToConsole(val)  

        /// <summary>
        /// 使用此方法触发委托回调
        /// </summary>
        /// <param name="from">开始</param>
        /// <param name="to">结束</param>
        /// <param name="fb">委托引用</param>
        private static void Counter(int from,int to, Feedback fb)
        {
            for (int val = from; val <= to; val++)
            {
                // fb不为空,则调用回调方法
                if (fb != null)
                {
                    fb(val);
                }
                //fb?.Invoke(val); 简化版本调用
            }
        }  

4.定义Counter的方法调用(这一步可有可无,为了区分静态和实例方法就写了)

第一次调用Counter,传递Null,在回调方法里有一步判空操作,所以是不回调用回调函数的。第二个Counter调用正常传递参数,构造一个委托对象并绑定了一个方法


/// <summary>
        /// 静态调用
        /// </summary>
        private static void StaticDelegateDemo()
        {
            Console.WriteLine("---------委托调用静态方法------------");
            Counter(1, 10, null);
            Counter(1, 10, new Feedback(FeedbackToConsole));
            
            

        }

        /// <summary>
        /// 实例调用
        /// </summary>
        private static void InstanceDelegateDemo()
        {
            Console.WriteLine("---------委托调用实例方法------------");
            Program p = new Program();
            Counter(1, 10, null);
            Counter(1, 5, new Feedback(p.InstanceFeedbackToConsole));
        }  

 5. 查看控制台信息

完整代码:


 class Program
    {
        // 定义委托,并引用一个方法,这个方法需要获取一个int型参数返回void
        internal delegate void Feedback(int value);
        static void Main(string[] args)
        {
          
            StaticDelegateDemo();
            InstanceDelegateDemo();
            Console.ReadKey();
        }
        
        /// <summary>
        /// 静态调用
        /// </summary>
        private static void StaticDelegateDemo()
        {
            Console.WriteLine("---------委托调用静态方法------------");
            Counter(1, 10, null);
            Counter(1, 10, new Feedback(FeedbackToConsole));
           

        }

        /// <summary>
        /// 实例调用
        /// </summary>
        private static void InstanceDelegateDemo()
        {
            Console.WriteLine("---------委托调用实例方法------------");
            Program p = new Program();
            Counter(1, 10, null);
            Counter(1, 5, new Feedback(p.InstanceFeedbackToConsole));
        }


        /// <summary>
        /// 静态回调方法
        /// </summary>
        /// <param name="value"></param>
        private static void FeedbackToConsole(int value)
        {
            // 依次打印数字
            Console.WriteLine("Item=" + value);
        }
        /// <summary>
        /// 实例回调方法
        /// </summary>
        /// <param name="value"></param>
        private void InstanceFeedbackToConsole(int value)
        {
            Console.WriteLine("Item=" + value);
        }
    }  
View Code

 

启动控制台:可以看到已经成功把数字打印出来了

6. 委托链:委托链是委托对象的集合。可以利用委托链调用集合中的委托所绑定的全部方法。继续在原有的基础上添加委托链的方法。

新添加的两个方法本质上没有区别都是对委托链的实现,不同的是写法,明显是第二个方法更加精简一些。这是因为C#编译器重载了+=和-=操作符,这两个操作符分别调用Combine和Remove。


/// <summary>
        /// 委托链调用 1
        /// </summary>
        /// <param name="p"></param>
        private static void ChainDelegateDemo(Program p)
        {
            Console.WriteLine("---------委托链调用1------------");
            Feedback fb1 = new Feedback(FeedbackToConsole);
            Feedback fb2 = new Feedback(p.InstanceFeedbackToConsole);
            Feedback fbChain = null;
            fbChain = (Feedback)Delegate.Combine(fbChain, fb1);
            fbChain = (Feedback)Delegate.Combine(fbChain, fb2);
            Counter(1, 3, fbChain);
            Console.WriteLine();
            fbChain = (Feedback)Delegate.Remove(fbChain, new Feedback(FeedbackToConsole));
            Counter(1, 3, fbChain);
        }

        /// <summary>
        /// 委托链调用 2
        /// </summary>
        /// <param name="p"></param>
        private  static void ChainDelegateDemo2(Program p)
        {
            Console.WriteLine("---------委托链调用2------------");
            Feedback fb1 = new Feedback(FeedbackToConsole);
            Feedback fb2 = new Feedback(p.InstanceFeedbackToConsole);
            Feedback fbChain = null;
            fbChain += fb1;
            fbChain += fb2;
            Counter(1, 3, fbChain);
            Console.WriteLine();
            fbChain -= new Feedback(FeedbackToConsole);
            Counter(1, 2, fbChain);
        }  

在Main方法添加对委托链的调用:


 static void Main(string[] args)
        {
            Program p = new Program();
            StaticDelegateDemo();
            InstanceDelegateDemo();
            ChainDelegateDemo(p);
            ChainDelegateDemo2(p);
            Console.WriteLine("Hello World!");
            Console.ReadKey();
        }  

启动项目:

7. C#为委托提供的简化:

7.1 不需要构造委托对象:

之前的代码:

Counter(1, 10, new Feedback(FeedbackToConsole));

构造了一个委托对象并传递给Counter方法,由于C#编译器能自己推断。所以可以省略构造委托对象,直接传递方法。使代码的可读性更佳,也更容易理解。

简化后的代码:


        /// <summary>
        /// 静态调用
        /// </summary>
        private static void StaticDelegateDemo()
        {
            Console.WriteLine("---------委托调用静态方法------------");
            Counter(1, 10, null);
            //Counter(1, 10, new Feedback(FeedbackToConsole));
            Counter(1, 10, FeedbackToConsole);
            

        }      

可以看到效果是一样的:

7.2 简化语法:不需要定义回调方法(以lambda表达式实现)

在前面的代码中定义了一个回调方法:


        /// <summary>
        /// 静态回调方法
        /// </summary>
        /// <param name="value"></param>
        private static void FeedbackToConsole(int value)
        {
            // 依次打印数字
            Console.WriteLine("Item=" + value);
        }  

现在以lambda表达式方式实现:


        /// <summary>
        /// 静态调用
        /// </summary>
        private static void StaticDelegateDemo()
        {
            Console.WriteLine("---------委托调用静态方法------------");
            Counter(1, 10, null);
            //Counter(1, 10, new Feedback(FeedbackToConsole));
            //Counter(1, 10, FeedbackToConsole);
            Counter(1, 10, value => Console.WriteLine(value));

        }  

lambda表达式实际上是一个匿名函数。编译器在看到lambda之后会在类中自动定义一个新的私有方法。类似于之前写的回调方法FeedbackToConsole()。lambda必须匹配委托!

lambda的语法: 参数 => 返回值。

=>左边是要传入的参数,本例中是传入一个Int类型的变量,=>右边是具体的代码,相当于FeedbackToConsole(),{}中所做的操作

一些规则:

如果不传递参数: ()=>Console.WriteLine("Hello World!")

传递一个参数:(int n)=>Console.WriteLine(n.ToString())    或者去掉()和int  编译器会自己推断类型:n=>Console.WriteLine(n.ToString())

传递多个参数:(int n ,int m)=>Console.WriteLine(n.ToString())  或者编译器自己推断类型:(n , m)=>Console.WriteLine(n.ToString())

注:如果有一个方法需要多处调用或者方法里面的代码量较多。还是单独写一个方法较为理想。

最后看一下换成lambda的写法结果显示是否一样

 

全部代码:


    class Program
    {
        // 定义委托,并引用一个方法,这个方法需要获取一个int型参数返回void
        internal delegate void Feedback(int value);
        static void Main(string[] args)
        {
            Program p = new Program();
            StaticDelegateDemo();
            InstanceDelegateDemo();
            ChainDelegateDemo(p);
            ChainDelegateDemo2(p);
            Console.WriteLine("Hello World!");
            string[] names = { "Jeff", "Jee", "aa", "bb" };
            //char find = 'e';
            //names= Array.FindAll(names, name => name.IndexOf(find) >= 0);
            //Array.ForEach(names, Console.WriteLine);
            Console.ReadKey();
        }
        
        /// <summary>
        /// 静态调用
        /// </summary>
        private static void StaticDelegateDemo()
        {
            Console.WriteLine("---------委托调用静态方法------------");
            Counter(1, 10, null);
            //Counter(1, 10, new Feedback(FeedbackToConsole));
            //Counter(1, 10, FeedbackToConsole);
            Counter(1, 10, value => Console.WriteLine(value));

        }

        /// <summary>
        /// 实例调用
        /// </summary>
        private static void InstanceDelegateDemo()
        {
            Console.WriteLine("---------委托调用实例方法------------");
            Program p = new Program();
            Counter(1, 10, null);
            Counter(1, 5, new Feedback(p.InstanceFeedbackToConsole));
        }

        /// <summary>
        /// 委托链调用 1
        /// </summary>
        /// <param name="p"></param>
        private static void ChainDelegateDemo(Program p)
        {
            Console.WriteLine("---------委托链调用1------------");
            Feedback fb1 = new Feedback(FeedbackToConsole);
            Feedback fb2 = new Feedback(p.InstanceFeedbackToConsole);
            Feedback fbChain = null;
            fbChain = (Feedback)Delegate.Combine(fbChain, fb1);
            fbChain = (Feedback)Delegate.Combine(fbChain, fb2);
            Counter(1, 3, fbChain);
            Console.WriteLine();
            fbChain = (Feedback)Delegate.Remove(fbChain, new Feedback(FeedbackToConsole));
            Counter(1, 3, fbChain);
        }

        /// <summary>
        /// 委托链调用 2
        /// </summary>
        /// <param name="p"></param>
        private  static void ChainDelegateDemo2(Program p)
        {
            Console.WriteLine("---------委托链调用2------------");
            Feedback fb1 = new Feedback(FeedbackToConsole);
            Feedback fb2 = new Feedback(p.InstanceFeedbackToConsole);
            Feedback fbChain = null;
            fbChain += fb1;
            fbChain += fb2;
            Counter(1, 3, fbChain);
            Console.WriteLine();
            fbChain -= new Feedback(FeedbackToConsole);
            Counter(1, 2, fbChain);
        }
        /// <summary>
        /// 使用此方法触发委托回调
        /// </summary>
        /// <param name="from">开始</param>
        /// <param name="to">结束</param>
        /// <param name="fb">委托引用</param>
        private static void Counter(int from,int to, Feedback fb)
        {
            for (int val = from; val <= to; val++)
            {
                // fb不为空,则调用回调方法
                if (fb != null)
                {
                    fb(val);
                }
                //fb?.Invoke(val); 简化版本调用
            }
        }

        /// <summary>
        /// 静态回调方法
        /// </summary>
        /// <param name="value"></param>
        private static void FeedbackToConsole(int value)
        {
            // 依次打印数字
            Console.WriteLine("Item=" + value);
        }
        /// <summary>
        /// 实例回调方法
        /// </summary>
        /// <param name="value"></param>
        private void InstanceFeedbackToConsole(int value)
        {
            Console.WriteLine("Item=" + value);
        }
    }  
View Code

 

github:

https://github.com/xiaoMaPrincess/CSharp

转载于:https://www.cnblogs.com/jixiaosa/p/10687068.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#之委托 的相关文章

  • 搞定INTEL快速存储技术(用SSD硬盘做缓存加速)

    给朋友买了个联想 ideapad s400 超级本 xff0c 还真是锻炼我的 idea 啊 xff0c 原机不带 WIN7 系统 xff0c 所以只好自己动手装 WIN7 xff0c 并打开 24G SSD 硬盘做缓存 一 用常规方法 G
  • php取今天开始结束,PHP获取今天开始和结束的时间戳

    PHP获取今天开始和结束的时间戳 xff1a t 61 time 开始时间戳 start 61 mktime 0 0 0 date 34 m 34 t date 34 d 34 t date 34 Y 34 t 结束时间戳 end 61 m
  • Java中Semaphore(信号量)的使用

    Semaphore的作用 xff1a 在java中 xff0c 使用了synchronized关键字和Lock锁实现了资源的并发访问控制 xff0c 在同一时间只允许唯一了线程进入临界区访问资源 读锁除外 xff0c 这样子控制的主要目的是
  • git找回丢失的代码

    多人开发时找回丢失的代码 1 先保证所有分支的代码都已经提交并拉取到最新状态 2 最重要的是需要找到最近一条自己代码还存在的记录 xff0c 然后复制到最近的更早一条的提交记录的id xff0c 比如e36e9e76da144536c196
  • Docker容器进入的4种方式

    Docker容器进入的4种方式 在使用Docker创建了容器之后 xff0c 大家比较关心的就是如何进入该容器了 xff0c 其实进入Docker容器有好几多种方式 xff0c 这里我们就讲一下常用的几种进入Docker容器的方法 进入Do
  • HTTP Basic和Digest认证介绍与计算

    一 说明 web用户认证 xff0c 最开始是get提交 43 把用户名密码存放在客户端的cookie中的形式 xff1b 在意识到这样不安全之后逐渐演变成了post提交 43 把用户凭证放到了服务端的session中的形式 xff08 当
  • TeamViewer 的替代品 ZeroTier + NoMachine

    之前不怎么用 TeamViewer xff0c 最近用的多了 xff0c 特别好用 xff0c 有点上瘾 xff0c 在哪儿都能连家里的 RTX xff0c 太棒了 然后它就开始作了 有没有好的替代方案呢 xff1f 有人推荐向日葵 xff
  • Kubernetes tutorial - K8S 官方入门教程 中文翻译

    官方教程 xff0c 共 6 个小节 每一小节的第一部分是知识讲解 xff0c 第二部分是在线测试环境的入口 kubectl 的命令手册 原文地址 1 创建集群 1 1 使用 Minikube 创建集群 Kubernetes 集群 Kube
  • 两年,从纯小白到腾讯阿里,应届非计算机毕业生的2014互联网求职之路

    0 写在前面 以此文 xff0c 献给自己这两年的青葱岁月 xff0c 感谢淘宝的朗英师兄和微博的旭爷 全栈pm莹姐姐 酷炫石女王 以及我逝去的头发 参照Lucida的 9个offer xff0c 12家公司 xff0c 35场面试 一文
  • 在cmd中使用start运行exe文件闪退问题

    如果我们是使用的bat批处理文件来执行某件事 xff0c 我们可以直接使用 k参数 xff0c 或者pause命令来让容器 cmd 执行完文件后不退出 如果我们是在cmd中使用start或其他命令直接执行任务 xff0c 导致当前容器退出
  • GreenPlum 5.0的安装

    基本环境 xff1a serverIPMDW172 16 16 31SDW1172 16 16 34SDW2172 16 16 35 1 xff1a 检查操作系统是否符合要求 xff0c 以及系统设置 我这里使用的系统是CentOS 操作系
  • 转载:Pixhawk源码笔记八:添加新的参数

    转载 xff1a 新浪 64 WalkAnt 第九部分 添加新的参数 英文参考 xff1a http dev ardupilot com wiki code overview adding a new parameter 本节源自 xff1
  • Ubuntu(Linux) 下 unzip 命令使用详解

    1 功能作用 xff1a 解压缩zip文件 2 位置 xff1a usr bin unzip 3 格式用法 xff1a unzip Z opts modifiers file zip list x xlist d exdir 4 主要参数
  • Linux之Libcurl库的介绍与应用20170509

    一 LibCurl简介 LibCurl是免费的客户端URL传输库 xff0c 支持FTP FTPS HTTP HTTPS SCP SFTP TFTP TELNET DICT FILE xff0c LDAP等协议 xff0c 其主页是http
  • 面试问题之操作系统:动态链接库和静态链接库的区别

    动态链接库是一个可以被其它应用程序共享的程序模块 xff0c 其中封装了一些可以被共享的例程和资源 动态链接库文件名的扩展名一般是dll xff0c 也有可能是drv xff0c sys和fon xff0c 它和可执行文件 exe 非常类似
  • (uC/OS-II学习笔记) 消息邮箱&&消息队列

    原文出处 xff1a http www cnblogs com hebaichuanyeah 与信号量一样 xff0c 消息邮箱与消息列队都是一种事件块 消息邮箱可以在任务间实现信息传递 比如 xff0c 在任务1中发送一条消息 xff0c
  • rosbag使用--记录深度相机数据

    首先看一下教程 xff1a http wiki ros org openni launch Tutorials BagRecordingPlayback 知道了rosbag如何进行使用记录深度数据 但是按照以上教程记录下来的bag file
  • Postman 基本操作学习

    History 所有使用postman发送的request都会保存在这里 点击之后会在当前Tab打开 参考 xff1a Requests History Environments 这里用来设定当前request 发送时使用的环境 xff0c
  • linux内核去掉设备驱动,基于嵌入式Linux内核的系统设备驱动程序开发设计

    引言 Linux是一个遵循POSIX标准的免费操作系统 具有BSD和SYSV的扩展特性 与其他操作系统相比 xff0c 嵌入式Linux系统以其可应用于多种硬件平台 内核高效稳定 源码开放 软件丰富 网络通信和文件管理机制完善等优良特性而正
  • html onmouseover 注释掉,HTML onmouseover事件用法及代码示例

    将鼠标指针移到元素或其子元素上时 xff0c 将发生HTML中的DOM onmouseover事件 用法 在HTML中 xff1a 在JavaScript中 xff1a object onmouseover 61 function mySc

随机推荐

  • stylegan3自己导出的requirements.txt环境文件

    stylegan3官方给的环境文件是 environment yml xff0c 需要用conda安装 在linux上安装总会遇见奇奇怪怪的问题 xff0c 因此我导出requirements txt文件 xff0c 用pip安装 requ
  • html5 在线摄像头,HTML5在线摄像头使用

    HTML5在线摄像头应用 最近在搞一个考试系统 xff0c 系统要求要有随机拍照的功能 xff0c 并且摄像头能够收到js的控制 在线摄像头嘛 xff0c 就那两种实现的方式 xff1a cab或者flash 暂且不论本人从没学过的flas
  • STM32固件库文件编程结构思想的理解

    STM32的固件库文件功能相当完善 xff0c 提供的API完全能满足一般的项目需要 刚从51单片机转到STM32的人 xff0c 肯定会被这么庞大的东东吓到 xff0c 51单片机上对IO口操作 xff0c 简简单单几行代码就搞定了 xf
  • ekf pose使用方法 ros_【ROS-Gazebo】为什么选择SDF?

    前言 这是一个系列小文章 xff0c 主要介绍在ROS Gazebo中如何更好地使用SDF格式建模与仿真 众所周知 xff0c URDF是ROS的原生支持格式 xff0c 但在某些情况下 xff08 尤其是Gazebo仿真时 xff09 x
  • nvidia-smi命令执行很慢,如何改进

    初次安装好nvidia的驱动 xff0c 每次执行nvidia smi命令时 xff0c 要5秒以上 可通过如下命令进行改进 xff1a nvidia persistenced persistence mode 转载于 https www
  • 构建千万用户级别后台数据库架构

    关于如何构建千万级别用户的后台数据库架构话题 xff0c 在ITPUB及CSDN论坛都有不少网友提问 xff0c 新型问答网站知乎上也有人提问 xff0c 并且顺带梳理了下思路 xff0c 方便更多的技术朋友有章可循 xff0c 整理一篇抛
  • 酒店管理系统(功能结构图、流程图)

    酒店管理系统功能结构图 相关流程图 转载于 https www cnblogs com chouqiuqiu p 9035154 html
  • Linux下好用的屏幕录像软件kazam及截图软件shutter

    都是apt直接安装即可使用 其中kazam默认保存的文件格式是avi xff0c 非常大 xff0c 通常录制几十秒就已经好几个G xff0c 导致录制过程太占用资源 xff0c 会出现卡顿的现象 在 首选项 中可以选择输出格式为mp4 x
  • 禁用MOSS2007“我的网站”功能

    转载自 xff1a 禁用MOSS2007 我的网站 功能 建立完Moss2007的SSP服务之后 xff0c 默认会为所有验证用户打开 我的网站 的链接 xff0c 如下图所示 xff1a 并不是所有人都会需要这个功能的 xff0c 我们可
  • Linux搭建waf防火墙,Nginx使用Naxsi搭建Web应用防火墙(WAF),防xss、防注入

    一 说明 Naxsi是一个开放源代码 高效 低维护规则的Nginx web应用防火墙 Web Application Firewall 模块 Naxsi的主要目标是加固web应用程序 xff0c 以抵御SQL注入 跨站脚本 跨域伪造请求 本
  • 程序员、架构师、技术经理、技术总监和CTO有啥区别?

    http www javaranger com archives 1997 程序员 程序员 xff0c 英文名coder programmer xff0c 大家常自嘲叫码农的阶段 这个角色职责是把需求或产品实现为用户可用的软件产品 此职位为
  • 在linux上运行python脚本(安装pytorch踩坑记录,pyinstaller使用方式,构建docker镜像)

    背景 脚本需要导入pytorch等库才能运行 脚本在windows上运行成功 xff0c 尝试放到linux上运行 linux服务器内存较小 方法一 xff1a 在linux上安装依赖 把脚本放到linux上 xff0c 直接安装依赖 安装
  • ubuntu 16.04 配置静态ip 后默认的网卡eno1变成eth0了不能联网的问题解决

    我这次是在真实机器上面安装的ubuntu16 04 在配置了静态ip后不懂什么原因默认的eno1网卡变回了eth0网卡之后就不能上网 xff0c 同一个网段的其他集群节点也不能ping 通 因为ubuntu16 04的默认网卡不再是eth0
  • 快速测试端口的连通性(HTTP/HTTPS)

    ping 仅限 80 端口 xff0c 命令中无法指定端口 xff1a span class hljs label C span Users Administrator gt span class hljs built in ping sp
  • 支持 UTF-8 中文的串口调试工具

    支持 UTF 8 中文的串口调试工具 最近使用 mdk526 xff0c 编辑设置使用 utf 8 xff0c 编辑窗口中文正常 xff0c 但是编译的时候提示 warning 870 D invalid multibyte charact
  • Linux

    Linux服务 TOC mysql 关系型数据库 关系 就是一个一个的二维表 其中 表中的行 列次序并不重要 行 record 表中的每一行 又称为一条记录 列 column 表中的每一列 称为属性 字段 主键 primary key 是一
  • Eclipse怎么样添加智能感知提示功能(含Windows版和Mac版)

    近日感兴趣于安卓 xff0c 开始学习Android开发 第一次使用Eclipse xff0c 用久了VS xff0c 也习惯了他的智能提示 xff0c 刚转到Eclipse下实在是不习惯 网上有人说按Alt 43 可以实现单词补全功能 x
  • ORB-SLAM2:一种开源的VSLAM方案(译文)

    摘要 xff1a ORB SLAM2是基于单目 xff0c 双目和RGB D相机的一套完整的SLAM方案 它能够实现地图重用 xff0c 回环检测和重新定位的功能 无论是在室内的小型手持设备 xff0c 还是到工厂环境的无人机和城市里驾驶的
  • 双目视觉几何框架详解

    一 图像坐标 xff1a 我想和世界坐标谈谈 A 玉米竭力用轻松具体的描述来讲述双目三维重建中的一些数学问题 希望这样的方式让大家以一个轻松的心态阅读玉米的 计算机视觉学习笔记 双目视觉数学架构系列博客 这个系列博客旨在捋顺一下已标定的双目
  • C#之委托

    委托 xff1a 顾名思义 xff0c 让别人帮你办件事 委托是C 实现回调函数的一种机制 可能有人会问了 xff0c 回调函数是个啥 xff1f xff1f xff1f 举个例子 xff1a 我现在是一家公司的老板 xff0c 公司现在在