【C#】学习笔记(1) Delegates,Events,Lambda Expressions
C#是跟着杨老师的教程走的,在这里感谢一下老师的无私奉献,他的cnblog地址:>cgzl,他的B站地址:>solenovex。
进入正题:
Delegate表示委托,委托是一种数据结构,它引用静态方法或引用类实例及该类的实例方法。(引用官方文档的英文原话)
Represents a delegate, which is a data structure that refers to a static method or to a class instance and an instance method of that class.
看不懂没关系,我也看不懂,哈哈哈。
直接拿两个例子看一下,第一个是杨老师提供的。
using System; namespace Demo
{
class Program
{
// 定义一个名为Transformer的delegate类,参数类型int,返回类型int。
delegate int Transformer(int x);
// 定义一个静态类Square,这里用了Lambda表达式,同样的,参数类型为int,返回类型也是int。
static int Square(int x) => x * x;
static void Main(string[] args)
{
Transformer t = Square; //把Square方法当作变量传入委托变量t,这时创建了委托实例。
int result = t(); // 调用委托方法。
Console.WriteLine(result); // 输出结果:9
}
}
}
这里的 Transformer t= Square; 简写了,等效于Transformer t= new Transformer(Square);
也就是当调用t(3)(委托实例)时,先调用了委托,委托再去调用目标方法。画个图应该很好理解。

优点:解耦。
应用:编写插件式的方法
·方法是在运行时才赋值给委托变量的
using System; namespace Demo
{
public delegate int Transformer(int x); // 定义委托类要注意传入的类型和返回类型。 class Util
{
public static void Transform(int[] values, Transformer t)
{
for (int i = ; i < values.Length; i++)
{
values[i] = t(values[i]); // 委托实例t
}
}
}
class Program
{
static int Square(int x) => x * x;
public static void Main(string[] args)
{
int[] values = { , , };
Util.Transform(values, Square); // 这里调用Util的静态方法Transform,并传入参数。目标函数为Square
foreach (int i in values)
{
Console.WriteLine(i);
}
}
}
}
接下来看一下官方文档给的例子:>Delegate
using System; namespace Demo
{
public delegate String myMethodDelegate(int myInt); public class mySampleClass
{
public String myStringMethod(int myInt)
{
if (myInt>)
{
return ("positive");
}
if (myInt<)
{
return ("negative");
}
return ("zero");
}
public static String mySignMethod(int myInt)
{
if (myInt > )
{
return ("+");
}
if (myInt < )
{
return ("-");
}
return ("");
}
} class Program
{
public static void Main(string[] args)
{
// Creates one delegate for each method. For the instance method, an
// instance (mySC) must be supplied. For the static method, use the
// class name.
mySampleClass mySC = new mySampleClass();
myMethodDelegate myD1 = new myMethodDelegate(mySC.myStringMethod);
myMethodDelegate myD2 = new myMethodDelegate(mySampleClass.mySignMethod); // Invokes the delegates.
Console.WriteLine("{0} is {1}; use the sign \"{2}\".", , myD1(), myD2());
Console.WriteLine("{0} is {1}; use the sign \"{2}\".", -, myD1(-), myD2(-));
Console.WriteLine("{0} is {1}; use the sign \"{2}\".", , myD1(), myD2());
}
}
}
运行结果:

画个图分析一下:

多播委托
委托按着我自己的理解就是把别人的方法放到我这儿,要用的时候去拿,但是不是在我这儿拿,而是到别人那去。em
多播委托就是可以利用操作符+,-来创建新的委托实例,并赋值给当前的委托变量。
using System; namespace Demo
{
public delegate int Transformer(int x);
class Program
{
static int Square(int x)
{
var result = x * x;
Console.WriteLine(result);
return result;
}
static int Cube(int x)
{
var result = x * x * x;
Console.WriteLine(result);
return result;
}
public static void Main(string[] args)
{
Transformer t = null;
t += Square;
t += Cube;
t();
}
}
}
输出结果:

Square在先,它就先执行。
假如都进行-=移除,最后会报空指针异常。
委托实例里至少要有一个静态对象或者是实例对象,不然会抛出空指针异常。
A combining operation returns
nullwhen the result of the operation is a delegate that does not reference at least one method.
“委托是不可变的“
”Combine 和Remove实际上是创建新的委托实例,并把它赋给当前的委托变量”。
感觉自己理解有不对的地方,就先这样吧。
【C#】学习笔记(1) Delegates,Events,Lambda Expressions的更多相关文章
- Python学习笔记010——匿名函数lambda
1 语法 my_lambda = lambda arg1, arg2 : arg1 + arg2 + 1 arg1.arg2:参数 arg1 + arg2 + 1 :表达式 2 描述 匿名函数不需要r ...
- Java8学习笔记(一)--Lambda表达式
两个概念 函数式接口 函数式接口就是只显式声明一个抽象方法的接口.为保证方法数量不多不少,java8提供了一个专用注解@FunctionalInterface,这样,当接口中声明的抽象方法多于或少于一 ...
- c++学习笔记(七)- lambda表达式 迭代器 算法
关于lambda表达式: 刷题的时候遇到一句代码不懂: char ch = *it;auto it2 = find_if(it, b.end(), [ch](char x){ return x != ...
- Haskell语言学习笔记(79)lambda演算
lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...
- LINQ学习笔记——(2)Lambda表达式
最基本的 Lambda 表达式语法: (参数列表)=>{方法体} 说明: 参数列表中的参数类型可以是明确类型或者是推断类型 如果是推断类型,则参数的数据类型将由编译器根据上下文自动推断出 ...
- 【C#】学习笔记(3) 关于Events使用的小Demo
关于Events事件的简单Demo. 目录结构: Program.cs using System; namespace EventsDemo { class Program { static void ...
- Java8 学习笔记--函数式接口与lambda表达式的关系
在java中,lambda表达式与函数式接口是不可分割的,都是结合起来使用的. 对于函数式接口,我们可以理解为只有一个抽象方法的接口,除此之外它和别的接口相比并没有什么特殊的地方.为了确保函数式接口的 ...
- STM32F103X datasheet学习笔记---Interrupts and events
1.前言 本章主要介绍STM32中断和事件相关的内容 2.NVIC NVIC管理着包括内核异常等中断 主要特性 68个外部中断源(不包含16个内部中断线) 可编程优先级为16级 低延迟异常和中断处理 ...
- C#学习笔记三(委托·lambda表达式和事件,字符串和正则表达式,集合,特殊的集合)
委托和事件的区别 序号 区别 委托 事件 1 是否可以使用=来赋值 是 否 2 是否可以在类外部进行调用 是 否 3 是否是一个类型 是 否,事件修饰的是一个对象 public delegate vo ...
随机推荐
- linux下unzip解压报错“symlink error: File name too long”怎么办?提供解决方案。
点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 分享unzip工具的一个bug." 最近在研究菠菜站,中间用到了Spidermonkey,碰到一些小波折,在这里分享出来,以便大家 ...
- JS 对象定义
JS 对象 JavaScript 中的所有事物都是对象:字符串.数值.数组.函数... 此外,JavaScript 允许自定义对象. JavaScript 对象 JavaScript 提供多个内建对象 ...
- iOS与JS交互-WKWebView
iOS移动端应用中,一般都会嵌入网页,在网页中处理的结果需要反馈给iOS让移动端做出相应的处理(例如页面跳转), 1.webview的配置 2.代理方法中拿到事件进行处理 二.JS中的配套出发事件 当 ...
- Centos 静态网络配置
cat /etc/sysconfig/network-scripts/ifcfg-ens33 DEFROUTE="yes" IPV4_FAILURE_FATAL="no& ...
- 手工挖掘web常见漏洞时的一些经验总结
一.前提: 漏洞挖掘原则 所有变量 所有头 cookie中的变量 逐个变量删除 漏洞的本质 数据与指令的混淆 对用户输入信息过滤不严判断失误,误将数据当指令 二.经典漏洞: 1.身份认证 常用弱口令/ ...
- LeetCode 1245 树的直径
地址 https://leetcode-cn.com/contest/biweekly-contest-12/problems/tree-diameter/ 给你这棵「无向树」,请你测算并返回它的「直 ...
- C++ class内类型重载,operator Type()
#include <iostream> // operator Type() 类型操作符重载 // operator int() // operator double() // ... / ...
- 设计模式-Template(行为模式) 采用 继承的方式 将算法封装在抽象基类中,在子类中实现细节。利用面向对象中的多态实现算法实现细节和高层接口的松耦合。
以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Template.h class AbstractClass { public: virtual ~AbstractCla ...
- 使用adb安装apk到手机
[ADB]Android debug bridge.Android手机实际是基于Linux系统的.通过USB线将android手机与电脑连起来,在电脑上dos命令行中敲adb shell命令,可以登录 ...
- P3525 INS-Inspection
这道题的题面有点问题,如果按照题面做,应该是A不了的,下面引用一下评论里@REM_001的翻译 一棵n个节点的树,行动中心S从1->N.从S出发前往任意一个未标记到的点(沿树上两点的唯一路径走) ...