[转载]C#委托与事件--简单笔记
原文地址:https://www.cnblogs.com/joeymary/p/8486358.html
委托
简单记录点东西 适合似懂非懂的朋友看看
委托类型用来定义和响应应用程序中的回调。
借此可以设计各种有面向对象特性的代码模式。下面要说的事件在我看来就是委托的一种实现,再深一步讲,利用委托加事件,是不是可以构建各种所谓的管道框架。
如ASP.NET WebAPI的管道模型,整个消息处理管道是通过一组有序的HttpMessagHandler“首尾相连”而成,具体实现“串联”的是通过DelegatingHandler这个类型来完成的。即是一组委托链。
最精华的内容您已看完
委托定义 public delegate int DeleName(int x);
名称
参数
返回值
1、委托简单示例
DeleName del = M1;
public int M1(int i)
{
...
}
入门理解1:委托是方法的类型,即委托=class,方法=new class()
上面的方法名称M1只起到传递作用时,可以用匿名委托代替:
DeleName del = delegate (int i)
{
...
};
除了用匿名委托,还可以用lamda表达式进行代替:
DeleName del = (int i)=>
{
...
};
在这里也能看出lamda本质就是委托
2、泛型委托
public delegate void MyGenericDelegate1<T>(T arg);
public delegate int MyGenericDelegate2<T,M>(T arg,M name);
MyGenericDelegate1<int> intTarget = new MyGenericDelegate<int>(IntTarget);
static void IntTarget(int arg) => Console.WriteLine($"IntTarget--> {++arg}");
MyGenericDelegate2<int,string> intTarget1 = (int arg,string name) =>
{
return 1;
};
好处:封装为了复用
看下上面两个委托的命名:MyGenericDelegate1 MyGenericDelegate2 纯粹为了取名而取名,此时我们可以不自己取名。
怎么做呢,C#本身提供了两个泛型委托可以给我们使用,且可满足大多数场景。
3、泛型Action<> 和 Func<> 委托
(可指向至多传递16个参数的方法)
Action<>:无返回值: 定义 public delegate void Action<...>
public static void Show()
{
// 使用Action<>委托来指向 DisplayMessage()
Action<string, ConsoleColor, int> actionTarget = new Action<string, ConsoleColor, int>(DisplayMessage);
actionTarget("actionTarget", ConsoleColor.Red, 5);
}
// Action<> 委托的一个目标
private static void DisplayMessage(string msg, ConsoleColor txtColor, int printCount)
{
...
}
Func<>:有返回值 public delegate TResult Func<..., out TResult> TResult:返回值类型
Func<int, int, int> funcTarget = new Func<int, int, int>(Add);
funcTarget(1, 2);
static int Add(int x, int y) => x + y;
如果你觉得一个具有自定义名称的委托更有助于捕获问题范畴,那么构建自定义委托不过就是一行代码的事儿。
注:Linq中就大量的用到了 Action<> 和 Func<>。
4、事件
最简单的说法是:可以把事件看成是委托的一个实例。委托比作类:它定义了函数的签名(接受什么类型的参数 返回什么类型的值)事件比作委托new出来的一个实例,是具有该委托签名的具体函数。当然事件和实例也是有区别的:
1、事件这个东西 能容纳很多个具体的函数(通过+= -= 增加删除)。
2、事件有event关键字起到了保护作用不允许改变事件的引用。即在声明事件的类外部不能用=对事件对象赋值
直接看看代码
public delegate void HelloWorldDelegate(string name);
public class HelloWorldClass2
{
public event HelloWorldDelegate del;//!!!!event修饰了委托对象
public void HelloWorld(string name)
{
//del = (n) => { Console.WriteLine(n); };//在声明事件的类内部可以用=直接定义事件的引用(赋值)
del(name);
}
}
class Program
{
static void Main(string[] args)
{
HelloWorldClass2 h2 = new HelloWorldClass2();
//h2.del = ByEnglish;//不允许改变事件的引用(不能用=赋值)
h2.del += ByEnglish;//第一种
//手工创建一个委托变量是最直接的方式。但是大多数情况下,我们并不依靠委托对象。我们可以使用C#提供的方法组转换的方法,它允许我们在调用以委托作为参数的方法时直接提供了与委托期望的签名想匹配的方法的名称(返回 void,参数 string),而不是创建委托对象。(所以一般直接用上面这种)
HelloWorldDelegate de = ByChinese;
h2.del += de;//第二种
h2.HelloWorld("mary");
Console.ReadLine();
}
static void ByEnglish(string name)
{
Console.WriteLine("hello,world"+name);
}
static void ByChinese(string name)
{
Console.WriteLine("你好,世界" + name);
}
}
事件默认是个多播委托,什么是多播委托呢?就是上面的h2.del委托容纳的方法有多个,ByEnglish跟ByChinese,用+=可以继续往下延伸。
委托和事件的区别在于,事件是个规约,委托是个实现(当然抽象上的委托也可以不是个具体的实现)。
规约的含义是,我定义了这么个语法,你可以通过+=和-=把委托挂载到这个东西(事件)上,当发生这个事件的时候,我会确保这些委托都被得到调用。但是具体是怎么调用的,你不用关心。
委托
简单记录点东西 适合似懂非懂的朋友看看
委托类型用来定义和响应应用程序中的回调。
借此可以设计各种有面向对象特性的代码模式。下面要说的事件在我看来就是委托的一种实现,再深一步讲,利用委托加事件,是不是可以构建各种所谓的管道框架。
如ASP.NET WebAPI的管道模型,整个消息处理管道是通过一组有序的HttpMessagHandler“首尾相连”而成,具体实现“串联”的是通过DelegatingHandler这个类型来完成的。即是一组委托链。
最精华的内容您已看完
委托定义 public delegate int DeleName(int x);
名称
参数
返回值
1、委托简单示例
DeleName del = M1;
public int M1(int i)
{
...
}
入门理解1:委托是方法的类型,即委托=class,方法=new class()
上面的方法名称M1只起到传递作用时,可以用匿名委托代替:
DeleName del = delegate (int i)
{
...
};
除了用匿名委托,还可以用lamda表达式进行代替:
DeleName del = (int i)=>
{
...
};
在这里也能看出lamda本质就是委托
2、泛型委托
public delegate void MyGenericDelegate1<T>(T arg);
public delegate int MyGenericDelegate2<T,M>(T arg,M name);
MyGenericDelegate1<int> intTarget = new MyGenericDelegate<int>(IntTarget);
static void IntTarget(int arg) => Console.WriteLine($"IntTarget--> {++arg}");
MyGenericDelegate2<int,string> intTarget1 = (int arg,string name) =>
{
return 1;
};
好处:封装为了复用
看下上面两个委托的命名:MyGenericDelegate1 MyGenericDelegate2 纯粹为了取名而取名,此时我们可以不自己取名。
怎么做呢,C#本身提供了两个泛型委托可以给我们使用,且可满足大多数场景。
3、泛型Action<> 和 Func<> 委托
(可指向至多传递16个参数的方法)
Action<>:无返回值: 定义 public delegate void Action<...>
public static void Show()
{
// 使用Action<>委托来指向 DisplayMessage()
Action<string, ConsoleColor, int> actionTarget = new Action<string, ConsoleColor, int>(DisplayMessage);
actionTarget("actionTarget", ConsoleColor.Red, 5);
}
// Action<> 委托的一个目标
private static void DisplayMessage(string msg, ConsoleColor txtColor, int printCount)
{
...
}
Func<>:有返回值 public delegate TResult Func<..., out TResult> TResult:返回值类型
Func<int, int, int> funcTarget = new Func<int, int, int>(Add);
funcTarget(1, 2);
static int Add(int x, int y) => x + y;
如果你觉得一个具有自定义名称的委托更有助于捕获问题范畴,那么构建自定义委托不过就是一行代码的事儿。
注:Linq中就大量的用到了 Action<> 和 Func<>。
4、事件
最简单的说法是:可以把事件看成是委托的一个实例。委托比作类:它定义了函数的签名(接受什么类型的参数 返回什么类型的值)事件比作委托new出来的一个实例,是具有该委托签名的具体函数。当然事件和实例也是有区别的:
1、事件这个东西 能容纳很多个具体的函数(通过+= -= 增加删除)。
2、事件有event关键字起到了保护作用不允许改变事件的引用。即在声明事件的类外部不能用=对事件对象赋值
直接看看代码
public delegate void HelloWorldDelegate(string name);
public class HelloWorldClass2
{
public event HelloWorldDelegate del;//!!!!event修饰了委托对象
public void HelloWorld(string name)
{
//del = (n) => { Console.WriteLine(n); };//在声明事件的类内部可以用=直接定义事件的引用(赋值)
del(name);
}
}
class Program
{
static void Main(string[] args)
{
HelloWorldClass2 h2 = new HelloWorldClass2();
//h2.del = ByEnglish;//不允许改变事件的引用(不能用=赋值)
h2.del += ByEnglish;//第一种
//手工创建一个委托变量是最直接的方式。但是大多数情况下,我们并不依靠委托对象。我们可以使用C#提供的方法组转换的方法,它允许我们在调用以委托作为参数的方法时直接提供了与委托期望的签名想匹配的方法的名称(返回 void,参数 string),而不是创建委托对象。(所以一般直接用上面这种)
HelloWorldDelegate de = ByChinese;
h2.del += de;//第二种
h2.HelloWorld("mary");
Console.ReadLine();
}
static void ByEnglish(string name)
{
Console.WriteLine("hello,world"+name);
}
static void ByChinese(string name)
{
Console.WriteLine("你好,世界" + name);
}
}
事件默认是个多播委托,什么是多播委托呢?就是上面的h2.del委托容纳的方法有多个,ByEnglish跟ByChinese,用+=可以继续往下延伸。
委托和事件的区别在于,事件是个规约,委托是个实现(当然抽象上的委托也可以不是个具体的实现)。
规约的含义是,我定义了这么个语法,你可以通过+=和-=把委托挂载到这个东西(事件)上,当发生这个事件的时候,我会确保这些委托都被得到调用。但是具体是怎么调用的,你不用关心。
[转载]C#委托与事件--简单笔记的更多相关文章
- C#委托与事件--简单笔记
委托 简单记录点东西 适合似懂非懂的朋友看看 委托类型用来定义和响应应用程序中的回调. 借此可以设计各种有面向对象特性的代码模式.下面要说的事件在我看来就是委托的一种实现,再深一步讲,利用委托加事件, ...
- C#委托与事件学习笔记
委托事件学习笔记 本文是学习委托和事件的笔记,水平有限,如有错漏之处,还望大神不吝赐教. 什么是委托?从字面意思来解释,就是把一个动作交给别人去执行.在实际开发中最常用的就是使一个方法可以当做一个参数 ...
- [转载]C#委托和事件(Delegate、Event、EventHandler、EventArgs)
原文链接:http://blog.csdn.net/zwj7612356/article/details/8272520 14.1.委托 当要把方法作为实参传送给其他方法的形参时,形参需要使用委托.委 ...
- Silverlight项目笔记1:UI控件与布局、MVVM、数据绑定、await/async、Linq查询、WCF RIA Services、序列化、委托与事件
最近从技术支持转到开发岗,做Silverlight部分的开发,用的Prism+MVVM,框架由同事搭好,目前做的主要是功能实现,用到了一些东西,侧重于如何使用,总结如下 1.UI控件与布局 常用的主要 ...
- (.NET高级课程笔记)委托、事件总结
1.委托的声明.实例化和调用 同样的,也可以把事务写成上面的形式 2.泛型委托---Func.Action 3.委托的意义:解耦 4.委托的意义:异步多线程 5.委托的意义:多播委托 6.观察者模 ...
- [转载]C#深入分析委托与事件
原文出处: 作者:风尘浪子 原文链接:http://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html 同类链接:http://www.c ...
- C#委托与事件的简单使用
前言:上一篇博文从原理和定义的角度介绍了C#的委托和事件.本文通过一个简单的小故事,来说明C#委托与事件的使用方法及其方便之处. 在阅读本文之前,需要你对委托和事件的基本概念有所了解.如果你是初次接触 ...
- C# 委托和事件(一):最简单的委托和事件
C#的事件基于委托,所以先说委托. 一切脱离实际场景的抽象概念新手看上去就像是在扯犊子,不错,我就是个新手.所以我需要一个实际的场景. 明天刚好考试(商务英语),考试上有两个角色(class):老师( ...
- 转载:C#中事件和委托的编译代码
接上文转载:C#中事件的由来,这时候,我们注释掉编译错误的行,然后重新进行编译,再借助Reflactor来对 event的声明语句做一探究,看看为什么会发生这样的错误: public event Gr ...
随机推荐
- wdcpV3面板安装ssl证书 apache教程 子站SSL配置
本帖最后由 q1082121 于 2016-11-24 12:31 编辑 方案二 apache1.把apache类型的ssl三个文件上传到:/www/wdlinux//www/wdlinux/http ...
- leetCode题解之判断一个句子中的字符和数字是否构成回文
1.问题描述 Given a string, determine if it is a palindrome, considering only alphanumeric characters and ...
- InputStream转换为String, byte[] data = new byte[1024]详解
/** * This file created at 2018年2月28日. * * Copyright (c) 2002-2018 Bingosoft, Inc. All rights reserv ...
- NSArray排序方法讲解
NSArray排序方法讲解 给数组排序有着多种方式 最麻烦的是sortedArrayUsingSelector:,其次是sortedArrayUsingDescriptors:,最容易使用的就是sor ...
- tkinter入门,canvas实现百度,抖音,加载
对于tkinter的各个控件,可以参看 : https://blog.csdn.net/weixin_38532159/article/details/78379523 这个已经比较全面了 今天利用 ...
- Weblogic 设置优先引用web项目的jar包
在WEB-INF/weblogic.xml中进行如下配置: <container-descriptor> <prefer-web-inf-classes>true</pr ...
- C++ Primer Plus 第15章 友元、异常和其它
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/chudaxiakkk/article/details/30502807 第15章 友元.异常和其它 ...
- P2278 [HNOI2003]操作系统
题目描述 写一个程序来模拟操作系统的进程调度.假设该系统只有一个CPU,每一个进程的到达时间,执行时间和运行优先级都是已知的.其中运行优先级用自然数表示,数字越大,则优先级越高. 如果一个进程到达的时 ...
- 【转】Android应用如何跳转到应用市场详情页面
Android应用开发过程中,可能会有需求,比如:推广时跳转到应用市场下载应用,跳转到应用市场给自己的应用打分,跳转到应用市场更新自己的应用.那如何跳转到应用市场呢? 可能跳转的方法大家都是知道的,方 ...
- 随手练——Uva-11584 划分成回文串(区间DP)
思路:dp[i]代表到第i位的最小值,枚举它的前几位,求出最小值. 转移方程:dp[ i ] = min(dp[ i ], dp[ j - 1 ] + 1 ) ; 本来觉得,代码加深部分可以提前bre ...