当前位置: 首页 > news >正文

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);
    }
}
2. 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);
    }
}

3. 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);
    }
}

4. 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);
    }
}
 

相关文章:

C#学习笔记

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

【A-006】基于SSH的新闻发布系统(含论文)

【A-006】基于SSH的新闻发布系统(含论文) 开发环境: Jdk7(8)Tomcat7(8)MySQLIntelliJ IDEA(Eclipse) 数据库: MySQL 技术: SpringStruts2HiberanteJSPJquery 适用于: 课程设计,毕业设计&…...

c语言-static

static作用&#xff1a;修饰变量和函数 修饰局部变量-静态局部变量 static未修饰局部变量 #include <stdio.h>void print() {int a 0;a;printf("%d ", a); }int main() {int i 0;for (i 0; i < 10; i){print();}return 0; }运行结果 static修饰局部变…...

zuul的性能调优

文章目录 zuul的性能调优Zuul参数剖析semaphore(信号量)ribbonhystrix高并发下常见Zuul异常熔断 zuul 1.x 与2.x的区别与总结 zuul的性能调优 在项目实践中&#xff0c;使用jemeter多线程并发访问微服务中的接口时候&#xff0c;在Zuul层出现异常、超时等&#xff0c;从而导致整…...

C++中的动态内存管理

1.C中动态内存管理 C语言内存管理方式在C中可以继续使用&#xff0c;但有些地方就无能为力&#xff0c;而且使用起来比较麻烦&#xff0c;因此C又提出了自己的内存管理方式&#xff1a;通过new和delete操作符进行动态内存管理。 1.1 new/delete操作内置类型 c语言和c的动态内存…...

es6的核心语法

在学习低代码时&#xff0c;经常有粉丝会问&#xff0c;低代码需要什么基础&#xff0c;es6就是基础中的一项。我们本篇是做一个扫盲&#xff0c;可以让你对基础有一个概要性的了解&#xff0c;具体的每个知识点可以深入进行了解&#xff0c;再结合官方模板就会有一个不错的掌握…...

Unity | 射线检测及EventSystem总结

目录 一、知识概述 1.Input.mousePosition 2.Camera.ScreenToWorldPoint 3.Camera.ScreenPointToRay 4.Physics2D.Raycast 二、射线相关 1.3D&#xff08;包括UI&#xff09;、射线与ScreenPointToRay 2.3D&#xff08;包括UI&#xff09;、射线与ScreenToWorldPoint …...

职业经验 2024 年测试求职手册

原贴地址: 2024 年测试求职手册 TesterHome 经历年前年后差不多 2 个月左右时候的求职&#xff0c;是时候总结复盘一下了&#xff0c;本打算在自己有着落再复盘&#xff0c;但是一想那时候似乎价值就没现在去做显得有意义一些&#xff0c;这篇帖子更多的是让大家看下有没有心…...

Spring Boot与Redis深度整合:实战指南

Spring Boot 整合 Redis 相当简单&#xff0c;它利用了 Spring Data Redis 项目&#xff0c;使得我们可以在 Spring Boot 应用中轻松地操作 Redis。以下是如何整合 Redis 到 Spring Boot 应用的基本步骤&#xff1a; 1. 添加依赖 首先&#xff0c;在你的 pom.xml 文件中添加 …...

微服务(基础篇-006-Docker安装-CentOS7)

目录 05-初识Docker-Docker的安装_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1LQ4y127n4?p46&spm_id_frompageDriver&vd_source60a35a11f813c6dff0b76089e5e138cc 0.安装Docker 1.CentOS安装Docker 1.1.卸载&#xff08;可选&#xff09; 1.2.安装dock…...

前端-css-01

1.CSS 长度单位和颜色设置 1.1CSS 中的长度单位 px 像素 em 字体大小的倍数&#xff08;字体默认是16px&#xff09; % 百分比 1.2CSS 中的颜色设置方式 1.2.1使用颜色名表示颜色 red、orange、yellow、green、cyan、blue、purple、pink、deeppink、skyblue、greenyellow .…...

Java学习36-Java 多线程安全:懒汉式和饿汉式

JAVA种有两种保证线程安全的方式&#xff0c;分别叫懒汉式Lazy Initialization和饿汉式Eager Initialization&#xff0c;以下是他们的区别&#xff1a; 线程安全性&#xff1a; 懒汉式本身是非线程安全的&#xff0c;因为多个线程可能同时检查实例是否为null&#xff0c;并尝…...

sql常用之CASE WHEN THEN

sql常用之CASE WHEN THEN SQL中的 CASE 类似编程语言里的 if-then-else 语句&#xff0c;用做逻辑判断。可以用于SELECT语句中&#xff0c;也可以用在WHERE&#xff0c;GROUP BY 和 ORDER BY 子句&#xff1b;可以单独使用&#xff0c;也可以和聚合函数结合使用。 语法&#…...

【PduR路由】IPduM模块详细介绍

目录 1.IpduM功能简介 2.IpduM模块依赖的其他模块 2.1RTE (BSW Scheduler) 2.2PDU Router 2.3COM 3.IpduM功能详解 3.1 功能概述 3.2 I-PDU多路复用I-PDU Multiplexing 3.2.1 Definitions and Layout 3.2.2通用功能描述 General 3.2.3模块初始化 Initialization 3.…...

【MySQL】6.MySQL主从复制和读写分离

主从复制 主从复制与读写分离 通常数据库的读/写都在同一个数据库服务器中进行&#xff1b; 但这样在安全性、高可用性和高并发等各个方面无法满足生产环境的实际需求&#xff1b; 因此&#xff0c;通过主从复制的方式同步数据&#xff0c;再通过读写分离提升数据库的并发负载…...

Lucene及概念介绍

Lucene及概念介绍 基础概念倒排索引索引合并分析查询语句的构成 基础概念 Document&#xff1a;我们一次查询或更新的载体&#xff0c;对比于实体类 Field&#xff1a;字段&#xff0c;是key-value格式的数据&#xff0c;对比实体类的字段 Item&#xff1a;一个单词&#xff0…...

密码算法概论

基本概念 什么是密码学&#xff1f; 简单来说&#xff0c;密码学就是研究编制密码和破译密码的技术科学 例题&#xff1a; 密码学的三个阶段 古代到1949年&#xff1a;具有艺术性的科学1949到1975年&#xff1a;IBM制定了加密标准DES1976至今&#xff1a;1976年开创了公钥密…...

实时数仓之实时数仓架构(Hudi)

目前比较流行的实时数仓架构有两类&#xff0c;其中一类是以FlinkDoris为核心的实时数仓架构方案&#xff1b;另一类是以湖仓一体架构为核心的实时数仓架构方案。本文针对FlinkHudi湖仓一体架构进行介绍&#xff0c;这套架构的特点是可以基于一套数据完全实现Lambda架构。实时数…...

2022-04-15_for循环等_作业

for循环 编写程序数一下 1到 100 的所有整数中出现多少个数字9计算1/1-1/21/3-1/41/5 …… 1/99 - 1/100 的值&#xff0c;打印出结果求10 个整数中最大值在屏幕上输出9*9乘法口诀表二分查找 编写程序数一下 1到 100 的所有整数中出现多少个数字9 #include <stdio.h>in…...

脑机辅助推导算法

目录 一&#xff0c;背景 二&#xff0c;华容道中道 1&#xff0c;问题 2&#xff0c;告诉脑机如何编码一个正方形格子 3&#xff0c;让脑机汇总信息 4&#xff0c;观察图&#xff0c;得到启发式算法 5&#xff0c;根据启发式算法求出具体解 6&#xff0c;可视化 一&am…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

PydanticAI快速入门示例

参考链接&#xff1a;https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...

CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx

“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网&#xff08;IIoT&#xff09;场景中&#xff0c;结合 DDS&#xff08;Data Distribution Service&#xff09; 和 Rx&#xff08;Reactive Extensions&#xff09; 技术&#xff0c;实现 …...

当下AI智能硬件方案浅谈

背景&#xff1a; 现在大模型出来以后&#xff0c;打破了常规的机械式的对话&#xff0c;人机对话变得更聪明一点。 对话用到的技术主要是实时音视频&#xff0c;简称为RTC。下游硬件厂商一般都不会去自己开发音视频技术&#xff0c;开发自己的大模型。商用方案多见为字节、百…...

【Axure高保真原型】图片列表添加和删除图片

今天和大家分享图片列表添加和删除图片的原型模板&#xff0c;效果包括&#xff1a; 点击图片列表的加号可以显示图片选择器&#xff0c;选择里面的图片&#xff1b; 选择图片后点击添加按钮&#xff0c;可以将该图片添加到图片列表&#xff1b; 鼠标移入图片列表的图片&…...

多层PCB技术解析:从材料选型到制造工艺的深度实践

在电子设备集成度与信号传输要求不断提升的背景下&#xff0c;多层PCB凭借分层布局优势&#xff0c;成为高速通信、汽车电子、工业控制等领域的核心载体。其通过导电层、绝缘层的交替堆叠&#xff0c;实现复杂电路的立体化设计&#xff0c;显著提升空间利用率与信号完整性。 一…...