C#学习笔记

一、事件派发器

在C#中,事件派发器通常是指事件委托和事件处理程序的组合,用于实现一种观察者设计模式。它允许对象在状态发生变化时通知其他对象,从而实现对象之间的解耦。

事件派发器的基本组成部分:

事件委托(Event Delegate): 事件委托是一种特殊的委托,用于封装可以被调用的方法。它定义了事件的签名,即指定了事件处理程序方法的参数和返回类型。通常,事件委托声明在事件派发器类的外部,并且使用 delegate 关键字来定义。例如:

public delegate void MyEventHandler(object sender, EventArgs e);

事件(Event): 事件是事件委托的实例,它提供了一种触发事件和订阅事件的机制。在事件派发器类中声明事件,其他类可以通过订阅该事件来注册事件处理程序。事件通常使用event关键字声明。例如:

public event MyEventHandler MyEvent;

事件处理程序(Event Handler): 事件处理程序是一个方法,用于响应事件的发生。它必须具有与事件委托相同的签名。当事件被触发时,与该事件关联的事件处理程序将被调用。例如:

public void MyEventHandlerMethod(object sender, EventArgs e)

{

//其他逻辑

}

事件触发器(Event Trigger): 事件触发器是事件派发器类中的方法,用于触发事件。当某些条件满足时,调用事件触发器方法将会触发事件,从而执行与事件关联的事件处理程序。通常,事件触发器方法使用protected 或protected virtual修饰,以便子类可以重写它。例如:

protected virtual void OnMyEvent(EventArgs e)

{

MyEvent?.Invoke(this, e);

}

Invoke 方法用于触发事件,它的第一个参数是事件的发布者(通常是 this ,表示当前对象),第二个参数是一个包含事件信息的EventArgs 对象e。

示例:假设我们有一个游戏中的角色类 Player,我们想要在角色受到伤害时触发一个事件来通知其他对象,比如显示受伤效果或更新 UI。

首先,定义一个事件委托和一个事件:

using System;

public class Player

{

// 事件委托

public delegate void DamageEventHandler(int damageAmount);

// 事件

public event DamageEventHandler Damaged;

// 触发受伤事件的方法

public void TakeDamage(int damageAmount)

{

//触发受伤事件

OnDamaged(damageAmount);

}

//触发事件的方法

protected virtual void OnDamaged(int damageAmount)

{

//检查事件是否有订阅者,如果有则调用事件处理程序

Damaged?.Invoke(damageAmount);

}

}

在这个例子中,DamageEventHandler 是一个事件委托,定义了一个受伤事件的签名,即参数为受到的伤害值。Damaged 是一个事件,它使用了 DamageEventHandler 委托。

再创建一个订阅事件的类 DamageEffect,用于处理角色受到伤害时的效果:

using System;

public class DamageEffect

{

// 受伤事件处理程序

public void OnPlayerDamaged(int damageAmount)

{

Console.WriteLine("角色受到伤害的效果");

}

}

最后,创建一个 Main 方法来模拟游戏的运行过程,并进行事件的订阅和触发:

class Program

{

static void Main(string[] args)

{

Player player = new Player();

DamageEffect damageEffect = new DamageEffect();

player.Damaged += damageEffect.OnPlayerDamaged;// 订阅事件

player.TakeDamage(20); // 触发事件

}

}

在Main方法中,创建了 Player 和 DamageEffect 的实例,并将 DamageEffect 的QnPlayerDamaged 方法订阅到了 Player 的 Damaged 事件上。

然后,通过调用 TakeDamage 方法来模拟角色受到了20点伤害,这将触发Damaged事件,最终调用 QnPlayerDamaged 方法,显示了受伤效果并输出了相应的信息。这是因为通常在 C# 中,事件可以被订阅,而当事件被触发时,所有订阅了该事件的方法都会被调用。

二、定时器

C#中的四种常用的定时器:

  1. System.Windows.Forms.Timer

System.Windows.Forms.Timer是Windows窗体应用程序中常用的定时器。它是基于消息循环的,工作在UI线程上,并且适用于Windows窗体应用程序的GUI更新。

示例:

using System;

using System.Windows.Forms;

public class MyForm : Form

{

private Timer timer;

public MyForm()

{

timer = new Timer();

timer.Interval = 1000; // 每秒触发一次

timer.Tick += Timer_Tick; // 订阅 Tick 事件

timer.Start(); // 启动定时器

}

private void Timer_Tick(object sender, EventArgs e)

{

Console.WriteLine("计时器触发时间: " + DateTime.Now);

}

}

  1. System.Threading.Timer

System.Threading.Timer是在.NET中常用的多线程环境下的定时器。它是基于线程池的,可以在一个独立的线程中触发回调函数。

示例:

using System;

using System.Threading;

public class MyTimer

{

private Timer timer;

public MyTimer()

{

timer = new Timer(TimerCallback, null, 0, 1000); // 每秒触发一次

}

private void TimerCallback(object state)

{

Console.WriteLine("计时器触发时间: " + DateTime.Now);

}

}

  1. System.Timers.Timer

System.Timers.Timer是在.NET中常用的定时器,类似于`System.Threading.Timer,但是它更适合于在单线程环境下使用,例如Windows服务等。

示例:

using System;

using System.Timers;

public class MyTimer

{

private Timer timer;

public MyTimer()

{

timer = new Timer(1000); // 每秒触发一次

timer.Elapsed += Timer_Elapsed; // 订阅 Elapsed 事件

timer.Start(); // 启动定时器

}

private void Timer_Elapsed(object sender, ElapsedEventArgs e)

{

Console.WriteLine("计时器触发时间: " + DateTime.Now);

}

}

  1. System.Windows.Threading.DispatcherTimer

System.Windows.Threading.DispatcherTimer是用于WPF应用程序的定时器,它与System.Windows.Forms.Timer类似,但是工作在WPF 的UI线程上。

示例:

using System;

using System.Windows.Threading;

public class MyViewModel

{

private DispatcherTimer timer;

public MyViewModel()

{

timer = new DispatcherTimer();

timer.Interval = TimeSpan.FromSeconds(1); // 每秒触发一次

timer.Tick += Timer_Tick; // 订阅 Tick 事件

timer.Start(); // 启动定时器

}

private void Timer_Tick(object sender, EventArgs e)

{

Console.WriteLine("计时器触发时间: " + DateTime.Now);

}

}

相关推荐
limengshi1383921 小时前
通信工程学习:什么是RIP路由信息协议
网络·网络协议·学习·智能路由器·信息与通信
xiaobuding_QAQ2 小时前
自用Proteus(8.15)常用元器件图示和功能介绍(持续更新...)
单片机·嵌入式硬件·学习·proteus
Starry_hello world2 小时前
二叉树实现
数据结构·笔记·有问必答
wei_shuo2 小时前
偏标记学习+图像分类(论文复现)
学习·分类·数据挖掘
Miqiuha3 小时前
lock_guard和unique_lock学习总结
java·数据库·学习
一 乐4 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
加油,旭杏5 小时前
【中间件学习】fastCG介绍和使用
学习·nginx·fastcgi
limengshi1383925 小时前
通信工程学习:什么是TFTP简单文件传输协议
网络·网络协议·学习·信息与通信
GFCGUO5 小时前
ubuntu18.04运行OpenPCDet出现的问题
linux·python·学习·ubuntu·conda·pip
丝丝不是土豆丝7 小时前
学习 CSS 新的属性 conic-gradient 实现环形进度条
学习