博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
什么是委托?
阅读量:5811 次
发布时间:2019-06-18

本文共 4551 字,大约阅读时间需要 15 分钟。

一,什么是委托?

在MSDN中写着:delegate 是一种可用于封装命名或匿名方法的引用类型。 委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。 

PS:针对这委托是类型安全和可靠的理解:委托本质是类,是强类型,.net下对象都是类型安全的(类型安全的原因:C#在编译期会检验类型,如果不一致则编辑器生成一个编译时错误)。

参照:http://bbs.csdn.net/topics/330140759

二,那可用于封装命名或匿名方法的引用类型怎么理解?

 委托:可以在不同对象之间传递方法,这个方法可以是命名方法,也可以是匿名方法。可以是静态方法,也可以是实例方法。而正是因为传的仅仅是方法名,看不到具体的实现,则这体现了封装的思想,并且委托的实现需要实例,同时证明委托也是引用类型。如下的例子:

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace delegateDemo{    class Program    {        public delegate void delegateInt();        static void Main(string[] args)        {            Test t = new Test();            //实现静态方法委托,传入方法名即可            delegateInt de = new delegateInt(Test.say);            //实现实例委托,传入方法名            delegateInt de2 = new delegateInt(t.say2);            de();            de2();            Console.ReadKey();        }    }    class Test    {        public static void say()        {            Console.WriteLine("我是委托");        }        public void say2()        {            Console.WriteLine("我是委托2");        }    }}

 匿名实现委托

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace delegateDe{    class Program    {        delegate void delegateNiName(string str);        static void Main(string[] args)        {            delegateNiName DelA = new delegateNiName(Test.say);            delegateNiName DelB = delegate(string s) { Console.WriteLine(s); };            delegateNiName DelC = (x) => { Console.WriteLine(x); };            // 实现委托            DelA("我是静态实现委托");            DelB("我是匿名实现委托1");            DelC("我是匿名实现委托2");            Console.ReadKey();        }    }    class Test    {        public static void say(string s)        {            Console.WriteLine(s);        }    }}

 三,delegate,event,Action<T> 和Func<T>又有什么区别:

1》先是event和delegate的区别:

1,事件是一种特殊的委托,或者说是受限制的委托,是委托一种特殊应用,只能施加+=,-=操作符。二者本质上是一个东西。

2,event只允许用add, remove方法来操作,这导致了它不允许在类的外部被直接触发,只能在类的内部适合的时机触发,委托可以在外部被触发。如下例子

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace delegateDiff{    class Test    {        // 编译代码后,使用 Visual Studio 2010自带的ILDASM.EXE反编译(简称IL),可知道:NET将委托定义为一个密封类,派生自基类System.MulticastDelegate,        //并继承了基类的三个方法        public delegate void DelegateTest();        public event DelegateTest EventIn; // 定义委托事件,这个EventIn只有委托的+=,或者-=,这个是一个特殊的委托        public DelegateTest DelegateIn;        public void Say()        {            if (this.EventIn != null)  //事件的触发,say方法被下面的main函数调用触发EventIn事件            {                this.EventIn();            }            if (this.DelegateIn != null)            {                this.DelegateIn();            }        }    }    class Program    {        static void EventTest()        {            Console.WriteLine("haha!我是事件");        }        static void DelegateTest()        {            Console.WriteLine("haha!我是委托");        }        static void Main(string[] args)        {            Test TestIn = new Test();            TestIn.DelegateIn += DelegateTest;            TestIn.EventIn += EventTest;            //别人触发方法的实现,事件和委托都可以            TestIn.Say();               //委托和事件的区别:委托可以自己触发实现,而事件则会报错            TestIn.DelegateIn();            // TestIn.EventIn();  // 事件触发会报错            Console.ReadKey();        }    }}

 2》Action<T>和Func<T>,则是.NET默认的委托类型,即是封装好的委托

1.Action<T>泛型Action<T>委托表示引用一个void返回类型的方法。

这个委托类存在16种重载方法。 例如Action<in T1,In T2>调用没有参数的方法

Action
action = i => Console.WriteLine(i); action("Hello");

 

2.Func<T>

Func<T>调用带返回类型的方法。有16种重载方法。 例如Func<out TResult>委托类型可以调用带返回类型且无参数的方法,

Func<in T,out TResult>委托类型调用带有4个参数和一个返回类型的方法。

     //func和表达式的使用            Expression
> ex = (i => i > 0); Func
func = ex.Compile(); var Test = func(5); //返回true //Func的定义和调用 Func
funcT = (i => { i = "Hello"; Console.WriteLine(i); return false; }); //Func的定义和调用,返回值类型自定义 Func
funcT1 = (i => { i = "Hello"; Console.WriteLine(i); return i; }); var Te1 = funcT1("Hello"); //返回输入内容 //Func的无参的时候的使用 Func
funcT2 = (() => { Console.WriteLine("Hello"); return false; }); var Te = funcT2(); //返回false //Func的无参的时候的使用,返回值类型自定义 Func
funcT3 = (() => { Console.WriteLine("Hello"); return "Hello"; }); var Te3 = funcT3(); //返回输入内容 if (funcT("Hello")) { Console.WriteLine("Hello"); } else { Console.WriteLine("World"); }

 

转载于:https://www.cnblogs.com/May-day/p/6438523.html

你可能感兴趣的文章
云原生的浪潮下,为什么运维人员适合学习Go语言?
查看>>
Webpack入门教程三十
查看>>
EAServer 6.1 .NET Client Support
查看>>
锐捷交换机密码恢复(1)
查看>>
Kali linux virtualbox rc=1908 错误解决办法
查看>>
linux软件包管理之三(源代码安装)
查看>>
数据库三范式是什么?
查看>>
[转载]设置Ubuntu自动连接无线,无须再输入密钥环和无线密码
查看>>
九叔Xen App测试报告
查看>>
Apache配置
查看>>
Ext gridPanel 单元格数据的渲染
查看>>
Android SDK 的下载代理
查看>>
Method Swizzling对Method的要求
查看>>
佛祖保佑,永不宕机
查看>>
四、配置开机自动启动Nginx + PHP【LNMP安装 】
查看>>
LNMP一键安装
查看>>
SQL Server数据库概述
查看>>
Linux 目录结构及内容详解
查看>>
startx命令--Linux命令应用大词典729个命令解读
查看>>
华为3026c交换机配置tftp备份命令
查看>>