事件(Event)

事件是将,委托的多播功能进行封装后的工具类型

什么是事件?

一个对象在完成某个工作后或者发生了某种操作后,需要通知其他对象,从而做出反映;发送出去的通知就是事件

class Enemy{

private int blood=100;

public void MinusBoold(int attack)

{

blood-=attack;

}

}

class Player{

public void DoAoE(Enemy[] enemies)

{

foreach(Enemy e in Enemies)

{

e.MinusBlood(10);

}

}

}

当Enemy中的MinusBlood更改了名字,Player的代码也需要随之更改

Player类中,显示调用了Enemy类的方法,则Player的代码“依赖”于Enemy类,构成了耦合关系

使用委托解耦合

在Player当中声明委托类型,将需要调用的减血方法在Player类外设置给内部的委托

class Player{
//声明委托,用来规定减血的方法应该符合怎样的方法签名
public delegate void OnAttackDelegate(int attack);
public OnAttackDelegate OnAttack=null;
public void DoAoE()
{
if(OnAttack!=null){
OnAttack(10);
}
}
}

问题:委托方法,需要携带的参数太多了,参数还会经常变动

方法:将所有参数都包含到一个class里面

C#为我们写好了事件专用委托定义

public delegate void EventHandler(object?sender,EventArge e);

事件对应的委托,不应该被类外界调用,只能由某个操作触发

事件对应的委托,不应该被外界直接赋值,只能够通过+、-增减委托方法

event关键字

class Player{
public event EventHandler OnAttack=null;
}

event事件规则

1、加event关键字修饰的委托,只能够定义在某个类

2、加event关键字修饰的委托,只能够被当前类内方法触发执行;类外不可触发执行

3、加event关键字修饰的委托,只能通过+、-增减委托方法,不可赋值

事件参数EventArray

事件被触发时可以传送自定义的事件参数

1、定义自己的事件参数包class

2、将EventHandler特化成传输咱们自己的参数包类型的委托类型

3、响应方法中,将事件参数包类型替换成我们自己的参数包类型

枚举类型

枚举类型是由基础整数数值的一组命名常量定义的值类型。若要定义枚举类型,请使用enemt关键子并指定枚举成员的名称。

枚举类型的基础使用

枚举时一个包含一组命名式常量的值类型数据,可以声明枚举类型的变量,并未其赋予枚举常量值

初始化特性

不允许null值直接赋予枚举成员,需先声明为可控值类型

默认无参数初始化的枚举成员值为0;

若赋予的整数值不存在于该枚举的元素中,则直接输出该整数值

常数值变更

枚举类型利用整数类型作为基本类型,默认为int,其元素的常量值由0开始递增1,也可以手动更改其数值,亦可通过强制转换使得枚举和整数相互替换

赋值特性

可以为所有枚举元素设置常熟值

若只为某一个元素设置常量值,则该元素后的元素的常量值据此以一递增

位逻辑运算操作

枚举类型表示选择组合,可以将必要区分选项的枚举元素对应的关联值设置为位区分分式的2的幂次数,即可以使用按位逻辑运算符|或&分别合并选项会交叉组合选项。若要只是枚举类型声明位字段,请对其应用Flags属性

//位区分式的2的幂次数

0b_0000_0001 //1
0b_0000_0010 //2
0b_0000_0100//4
 0b_0000_1000 //8
 0b_0001_0000 //16
 0b_0010_0000 //32

枚举元素的位逻辑运算特征

按位或可用于合选元素;

按位与可用于选出公共元素;

对于强制转换位枚举类型的整数值,会由枚举内的元素自动合选;

若不为能由所有元素按位或组合可能的取值,强制转换后仍为该整数值

字典

字典的Tkey必须是唯一的,而值不需要唯一

dictionary里面的元素都是一个键值对(由两个元素组成:键和值)

命名空间必须要有这个引用using System.Collections.Generic

字典的长度不是固定的 随着元素的增减而改变

键和值都可以是任何类型

格式:

Dictionary<键的类型,值的类型> 字典名=new Dictionary<键的类型,值的类型>();

字典名.Add(键,值) 增加元素

字典名[键]=值 修改元素

遍历时

字典.keys 字典的键

字典.Value 字典的值

字典 字典的键值对

字典。Remove (键) 移除元素

字典。ContainKey(键) 判断包含键不包含

字典。ContainValue(值) 判断包含值不包含

字典。Clear 移除所有元素

字典。count 字典元素的个数

匿名方式

在C#中,匿名函数是一种没有名字的方法,可以在代码中定义和使用。

我们已经提到过,委托是用于引用与其具有相同标签的方法,换句话说,你可以使用委托对象调用可由委托引用的方法。

匿名方法(Anonymous methods)提供了一种传递代码块作为委托参数的技术

在匿名方法中你不需要指定返回类型,它是从方法主体内return语句推断的


Lambda表达式

lambda表达式是一个简洁的语法,用于创建匿名函数,它们通常用于LINQ查询和委托


语法

(parameters) => expression
// 或
(parameters) => { statement; }

核心概念:给方法起名的烦恼

想象一下,你平时写代码就像给文件命名

  • 普通方法:就像你在电脑里建了一个文件,必须给它起个名字(比如 CalculateSum),存起来,以后要用就去文件夹里找它。
  • 匿名方法:就像你写了一张便利贴,上面写了一段逻辑,贴完即用,用完就扔,根本不需要给它起文件名。

为什么要用它?
当你只需要一段逻辑临时用一下(比如点击按钮后弹个窗,或者简单的加法计算),专门去写一个带名字的函数太麻烦了。匿名方法就是为了解决这种“一次性任务”而生的。

它长什么样?(语法)

匿名方法必须配合委托(Delegate)使用(你可以把委托理解为一个“容器”,专门用来装方法)。

它的核心标志就是 delegate 关键字。

对比一下你就懂了:

传统方式(有名字):

// 1. 先定义一个正经的方法

public static void SayHello(string name) {

Console.WriteLine("你好 " + name);

}

// 2. 把它赋值给委托

Action<string> myAction = SayHello;

匿名方式(没名字):

// 直接在委托里写代码,没有方法名

Action<string> myAction = delegate(string name) {

Console.WriteLine("你好 " + name);

};

 匿名方法 vs Lambda 表达式(重要!)

你可能会听到另一个词叫 Lambda 表达式(写法是 =>)。
通俗解释: Lambda 是匿名方法的“进化版”“极简版”

  • 匿名方法:写法稍微啰嗦一点,必须写 delegate 关键字。
  • Lambda:写法更帅、更短,用 => 符号。

现在的开发现状:
在现代 C# 开发中,大家99% 的情况都在用 Lambda (=>),因为它写起来最快。匿名方法属于“老前辈”,但在某些特殊场景下(比如想忽略参数列表时)还是会用到。

更多推荐