C#黑魔法:鸭子类型(Duck Typing)
C#黑魔法:鸭子类型(Duck Typing)
如果它走起路来像鸭子,叫起来像鸭子,那么它就是鸭子。
鸭子类型,主要应用于动态语言类型,比如JS、Python等,核心理念为:关注对象的行为(方法或属性)而非其具体类型。只要对象具备所需行为,即可在特定场景中使用,无需显式继承或实现接口。
来,在C#中使用鸭子类型
魔法:
await 不必是 Task和ValueTask
对象
TPL是官推荐的C#异步编程模型,几乎所有提到TPL异步编程时,都必须是async配合await,等待一个Task或ValueTask.
事实上,并不是只有 Task 和 ValueTask 才能 await:只要符合下列条件的类,都能await
- 类中包含 GetAwaiter() 实例方法:返回一个实现了 INotifyCompletion 接口的 awaiter 对象
- 类中包含 bool类型的 IsCompleted 属性:用于告知 awaiter 是否已经完成了其操作
- 类中包含一个 OnCompleted 方法:
说个秘密:.NET Core 中的 I/O 相关的异步 API 也的确是这么做的,I/O 操作过程中是不会有任何线程分配等待结果的,都是 coroutine 操作:I/O 操作开始后直接让出控制权,直到 I/O 操作完毕。
而之所以有的时候你发现 await 前后线程变了,那只是因为 Task 本身被调度了。
public class CustomTask<T>
{public CustomAwaiter<T> GetAwaiter(){return new CustomAwaiter<T>();}
}public class CustomAwaiter<T> : System.Runtime.CompilerServices.INotifyCompletion
{public bool IsCompleted { get; private set; }public T GetResult(){Console.WriteLine("获取异步结果");return default(T);}public void OnCompleted(Action continuation){Console.WriteLine("注册异步完成回调");IsCompleted = true;continuation?.Invoke();}
}var obj = new CustomTask<int>();
var r = await obj;
r.Display();
foreach 不必是 IEnumerable 和 IEnumerator
对象
满足以下条件的对象,就能使用 foreach:
- 类中只要有 GetEnumerator() 方法即可;
- GetEnumerator() 返回的对象包含一个 bool MoveNext() 方法加一个 Current 属性
//作为 GetEnumerator 方法的返回类
public class CustomEnumerator<T>
{public T Current { get; private set; }public bool MoveNext(){//这里写业务逻辑return false;}
}//只要有GetEnumerator方法,且返回值符合要求,就行了。
public class CustomEnumerable<T>
{public CustomEnumerator<T> GetEnumerator(){return new CustomEnumerator<T>();}
}//使用 foreach 查询
var names = new CustomEnumerable<string>();
foreach(var name in names)
{Console.WriteLine(name);
}
LINQ 不必是 IEnumerable对象
常见的Linq表达式语法:
var result = from q in source
where q.StartsWith("s")
select q;
代码中的 source 的类型不一定非要实现 IEnumerable 接口。
事实上,只要有对应名字的方法就可以了。比如:有了名为 Select 的方法就能用 select,有了名为 Where 的方法就能用 where
public class Custom<TSource>
{private readonly TSource value;public Custom(TSource value) { this.value = value; }public Custom<TResult> Select<TResult>(Func<TSource, TResult> selector){if (value == null){throw new ArgumentNullException(nameof(value));}if (selector == null){throw new ArgumentNullException(nameof(selector));}return new Custom<TResult>(selector(value));}public Custom<TSource> Where(Func<TSource, bool> predicate){var r = predicate(value);if (r){return this;}else{return null;}}public new string ToString() => $"自定义Linq类: {value}";
}
上面 Custom 类,有了 Select 和 Where 方法,就可以使用 linq表达式 select 和 where
//声明对象
var source = new Custom<string>("select");//使用linq表达式查询
var qResult = from m in source where m.StartsWith("s")select new { Name=source.ToString(), Age=1 };//结果(转化成一个匿名类)
Console.WriteLine(qResult.ToString());
using 对象, 不必实现 IDisposable接口
ref struct 因为必须在栈上且不能被装箱,所以不能实现接口。
只要 ref struct 对象中有一个 void Dispose() 方法,那么就可以用 using 语法实现对象的自动销毁。
//声明带 void Dispose()方法的引用类struct
ref struct MyRefStruct
{public string ToLower(string source){return source.ToLower();}public void Dispose(){//清理业务}
}//使用using语句,实现自动销毁
using (var myRef = new MyRefStruct())
{Console.WriteLine(myRef.ToLower("ABCEDF"));
}
普通类也能解构(非解析)
给一个普通类实现解构:只需要有一个名字为 Deconstruct() 的方法,并且参数都是 out 的即可。
class MyDeconstruct
{private int A => 1;private int B => 2;public void Deconstruct(out int a, out int b){a = A;b = B;}
}//实现解析操作
var x = new MyDeconstruct();
var (o, u) = x;
Console.WriteLine($"解构后,o={o},u={u}");
相关文章:
C#黑魔法:鸭子类型(Duck Typing)
C#黑魔法:鸭子类型(Duck Typing) 如果它走起路来像鸭子,叫起来像鸭子,那么它就是鸭子。 鸭子类型,主要应用于动态语言类型,比如JS、Python等,核心理念为:关注对象的行为(方法或属性…...
2025 年数维杯数学建模B题完整论文代码模型
《2025 年数维杯数学建模B题完整论文代码模型》 B题完整论文 一、赛事背景与题目总览 2025 年第十届数维杯大学生数学建模挑战赛的 B 题聚焦于“马拉松经济的高质量发展思路探索”。近年来,我国马拉松赛事如同一颗颗璀璨的星星,在城市的天空中闪耀&am…...
C++23 中的 views::chunk:深入探索与应用
文章目录 一、views::chunk 的背景与动机二、views::chunk 的基本用法语法与参数示例代码 三、views::chunk 的高级用法处理不完整块与 views::drop 和 views::take 结合 四、性能分析五、应用场景1. 批量处理数据2. 分页显示3. 并行处理 六、与其他范围适配器的组合1. 与 view…...
库室指静脉人脸门禁机 LK-BM-S10C/JR
1、采用大于等于四核处理器,主频大于1G; 2、内存≥4G DDR3;存储≥8G 3、核心模块采用国产工业级处理芯片和嵌入式Android实时多任务系统,采用模块化设计,模块间通过标准接口相连; 4、大于等于10英寸电容屏…...
低成本自动化改造的18个技术锚点深度解析
执行摘要 本文旨在深入剖析四项关键的低成本自动化技术,这些技术为工业转型提供了显著的运营和经济效益。文章将提供实用且深入的指导,涵盖老旧设备联网、AGV车队优化、空压机系统智能能耗管控以及此类项目投资回报率(ROI)的严谨…...
线程中常用的方法
知识点详细说明 Java线程的核心方法集中在Thread类和Object类中,以下是新增整合后的常用方法分类解析: 1. 线程生命周期控制 方法作用注意事项start()启动新线程,JVM调用run()方法多次调用会抛出IllegalThreadStateException(线程状态不可逆)。run()线程的任务逻辑直接调…...
运维体系架构规划
运维体系架构规划是一个系统性工程,旨在构建高效、稳定、安全的运维体系,保障业务系统的持续运行。下面从规划目标、核心模块、实施步骤等方面进行详细阐述: 一、规划目标 高可用性:确保业务系统 724 小时不间断运行,…...
C++结构体介绍
结构体的定义 在C中,结构体(struct)是一种用户定义的数据类型,允许将不同类型的数据组合在一起。结构体的定义使用struct关键字,后跟结构体名称和一对花括号{},花括号内包含成员变量的声明。 struct Pers…...
RoPE长度外推:外插内插
RoPE:假定 α \alpha α是定值 其中一半位置是用cos表示的 cos ( k α − 2 i d ) \cos(k\alpha^{-\frac{2i}{d}}) cos(kα−d2i)(另一半是sin)(d是词嵌入维度) 当太长如何解决: 1 直接不管—外插 缺点:超过一定长度性能急剧下降。(较大时,对应的很多位置编码…...
牛客练习赛138-题解
牛客练习赛138-题解 https://ac.nowcoder.com/acm/contest/109081#question A-小s的签到题 题目描述 给定一个比赛榜单: 第一行是 n 个不同的大写字母,代表题号第二行是 n 个形如a/b的字符串,表示每道题的通过人数和提交人数 找到通过人…...
MySQL高可用方案全攻略:选型指南与AI运维实践
MySQL高可用方案全攻略:选型指南与AI运维实践 引言:当数据库成为业务生命线 在数字化时代,数据库就是企业的"心脏"。一次数据库宕机可能导致: 电商网站每秒损失上万元订单游戏公司遭遇玩家大规模流失金融系统引发连锁反应本文将为你揭秘: MySQL主流高可用方案…...
【库(Library)、包(Package)和模块(Module)解析】
在Python中,**库(Library)、包(Package)和模块(Module)**是代码组织的不同层级,而import语句的导入行为与它们密切相关。以下是详细对比和解释: 📦 1. 核心概…...
记录一次使用thinkphp使用PhpSpreadsheet扩展导出数据,解决身份证号码等信息科学计数法问题处理
PhpSpreadsheet官网 PhpSpreadsheet安装 composer require phpoffice/phpspreadsheet使用composer安装时一定要下载php对应的版本,下载之前使用php -v检查当前php版本 简单使用 <?php require vendor/autoload.php;use PhpOffice\PhpSpreadsheet\Spreadshee…...
为什么业务总是被攻击?使用游戏盾解决方案
业务频繁遭受攻击的核心原因在于攻防资源不对等,攻击者利用技术漏洞、利益驱动及企业防护短板发起攻击,而游戏盾通过针对性架构设计实现高效防御。以下是具体分析与解决方案: 一、业务被攻击的根源 利益驱动攻击 勒索与数…...
4.1【LLaMA-Factory 实战】医疗领域大模型:从数据到部署的全流程实践
【LLaMA-Factory实战】医疗领域大模型:从数据到部署的全流程实践 一、引言 在医疗AI领域,构建专业的疾病诊断助手需要解决数据稀缺、知识专业性强、安全合规等多重挑战。本文基于LLaMA-Factory框架,详细介绍如何从0到1打造一个垂直领域的医…...
二维旋转矩阵:让图形动起来的数学魔法 ✨
大家好!今天我们要聊一个超酷的数学工具——旋转矩阵。它就像数学中的"旋转魔法",能让图形在平面上优雅地转圈圈。别被"矩阵"这个词吓到,其实它就是一个数字表格,但功能超级强大! 一、什么是旋转…...
go语言封装、继承与多态:
1.封装: 封装是通过将数据和操作数据的方法绑定在一起来实现的。在Go语言中,封装通过结构体(struct)和方法(method)来实现。结构体的字段可以通过大小写来控制访问权限。 package stutype Person struct …...
golang -- 如何获取变量类型
目录 前言获取变量类型一、fmt.Printf二、类型断言三、类型选择四、反射 reflect.TypeOf五、reflect.Value的Type()方法 前言 在学习反射的时候,对reflect包中获取变量类型的函数很迷惑 比如下面这个 用Type获取变量类型的方法(在下面提到) …...
Missashe考研日记-day36(改版说明)
Missashe考研日记-day36 改版说明 经过一天的思考、纠结和尝试,博主决定对更新内容进行改版,如下:1.不再每天都发一篇日记,改为一周发一篇包含一周七天学习进度的周记,但为了标题和以前相同(强迫症&#…...
opencv中的图像特征提取
图像的特征,一般是指图像所表达出的该图像的特有属性,其实就是事物的图像特征,由于图像获得的多样性(拍摄器材、角度等),事物的图像特征有时并不特别突出或与无关物体混杂在一起,因此图像的特征…...
一文了解氨基酸的分类、代谢和应用
氨基酸(Amino acids)是在分子中含有氨基和羧基的一类化合物。氨基酸是生命的基石,人类所有的疾病与健康状况都与氨基酸有直接或间接的关系。氨基酸失衡可引起肝硬化、神经系统感染性疾病、糖尿病、免疫性疾病、心血管疾病、肾病、肿瘤等各类疾…...
Linux 系统安装Minio详细教程
一、🔍 MinIO 简介 MinIO 是一个高性能的对象存储服务,兼容 Amazon S3 接口,适用于大数据、AI、云原生等场景,支持分布式部署和高可用性,可作为轻量级的私有云对象存储解决方案。 二、📦 安装准备 ✅ 系…...
排序算法-归并排序
归并排序是一种分治算法(Divide and Conquer)。对于给定的一组数据,利用递归与分治技术将数据序列划分成为越来越小的半子表,在对半子表排序后,再用递归方法将排好序的半子表合并成为越来越大的有序序列。 核心思想 分…...
js 两个数组中的指定参数(id)相同,为某个对象设置disabled属性
在JavaScript中,如果想要比较两个数组并根据它们的id属性来设置某个对象的disabled属性为true,你可以使用几种不同的方法。这里我将介绍几种常用的方法: 方法1:使用循环和条件判断 const array1 [{ id: 1, name: Item 1 },{ id…...
【Java基础】——集合篇
目标: 1.每个集合用的场景 2.每个集合的底层 一.概述 二. 三.Collection 1.通用方法 其中,contains方法,它的底层一定调用了equals方法进行比对,而且一定重写了equals方法,如果不重写equals方法,就是调用…...
小红书视频无水印下载方法
下载小红书(RED/Xiaohongshu)视频并去除水印可以通过以下几种方法实现,但请注意尊重原创作者版权,下载内容仅限个人使用,避免侵权行为。 方法一:使用在线解析工具(推荐) 复制视频链…...
代发考试战报:思科华为HCIP HCSE CCNP 考试通过
CCNP 300-410考试通过战报,HCIP云计算通过,HCIP数通 H12-821考试通过,H12-831考试通过,HCSP金融 H19-611考试通过,HCSE金融 H21-293 考试通过 报名考试一定要找正规报名,避免后续考试成绩被取消࿰…...
辉芒微离线烧录器“文件格式错误”问题解决
最近在使用辉芒微离线烧录器烧录程序时,提示“文件格式错误”,记录一下解决方法。 一、问题现象 经过多次尝试和排查,发现以下几种情况: 情况一:使用离线烧录器导入固件1(boot程序),…...
系统的从零开始学习电子的相关知识,该如何规划?
一、基础理论奠基(6-12个月) 1.1 数学与物理基础 核心内容: 微积分与线性代数(高频电路建模必备)复变函数与概率论(信号处理与通信系统基础)电磁场基础(麦克斯韦方程组的物理意义&…...
网络研讨会开发注册中, 5月15日特励达力科,“了解以太网”
在线研讨会主题 Understanding Ethernet - from basics to testing & optimization 了解以太网 - 从基础知识到测试和优化 注册链接# https://register.gotowebinar.com/register/2823468241337063262 时间 北京时间 2025 年 5 月 15 日 星期四 下午 3:30 - 4:30 适宜…...
LSTM的简单模型
好的,我来用通俗易懂的语言解释一下这个 LSTMTagger 类是如何工作的。 1️⃣ 类的目的 这个 LSTMTagger 类是一个用于自然语言处理(NLP)任务的模型,目的是标注输入的句子,通常用于词性标注(例如ÿ…...
聊聊Spring AI autoconfigure模块的拆分
序 本文主要研究一下Spring AI autoconfigure模块的拆分 v1.0.0-M6版本 (base) ➜ spring-ai-spring-boot-autoconfigure git:(v1.0.0-M6) tree -L 9 . ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── org │ │ │ └…...
LVGL源码学习之渲染、更新过程(3)---绘制和刷写
LVGL版本:8.1 往期回顾: LVGL源码学习之渲染、更新过程(1)---标记和激活 LVGL源码学习之渲染、更新过程(2)---无效区域的处理 前文提到,在处理完无效区域后,会得到一个个需要重新绘制的对象,这些对象将在DRAW事件中…...
CTF-DAY11
[NSSRound#16 Basic]了解过PHP特性吗 题目: <?php error_reporting(0); highlight_file(__FILE__); include("rce.php"); $checker_1 FALSE; $checker_2 FALSE; $checker_3 FALSE; $checker_4 FALSE; $num $_GET[num]; if (preg_match("/…...
手动修改uart16550的FIFO深度?
参考:修改AXI UART D16550 FIFO深度的过程记录 - lmore - 博客园...
Unity按钮事件冒泡
今天unity写程序时,我做了一个透明按钮,没图片,只绑了点击事件,把子对象文字组件也删了,空留一个透明按钮,此时运行时点击按钮是没有反应的,网上的教程说必须指定target graphic(目标…...
基于Llama3的开发应用(一):Llama模型的简单部署
Llama模型的简单部署 0 前言1 环境准备1.1 硬件环境1.2 软件环境 2 Meta-Llama-3-8B-Instruct 模型简介2.1 Instruct含义2.2 模型下载 3 简单调用4 FastAPI 部署4.1 通过FastAPI简单部署4.2 测试 5 使用 streamlit 构建简易聊天界面6 总结 0 前言 本系列文章是基于Meta-Llama-…...
人工智能 机器学习期末考试题
自测试卷2 一、选择题 1.下面哪个属性不是NumPy中数组的属性( )。 A.ndim B.size C.shape D.add 2.一个简单的Series是由( )的数据组成的。 A.两…...
修改docker为国内源
一、编辑docker配置文件 vi /etc/docker/daemon.json二、配置国内源和修改docker数据目录 {"registry-mirrors":["http://hub-mirror.c.163.com","https://mirrors.tuna.tsinghua.edu.cn","http://mirrors.sohu.com","https://u…...
C++八股 —— vector底层
vector底层为动态数组 类构成 class vector : protected _Vector_base_Vector_base: _M_start:容器元素开始的位置_M_finish:容器元素结束的位置_M_end_of_storage:动态内存最后一个元素的下一个位置 构造函数 无参构造 根据性能优先规则&a…...
postgresql 参数wal_level
wal_level决定多少信息写入到 WAL 中。默认值是replica,它会写入足够的数据以支持WAL归档和复制,包括在后备服务器上运行只读查询。minimal会去掉除从崩溃或者立即关机中进行恢复所需的信息之外的所有记录。最后,logical会增加支持逻辑解码所…...
Lightweight App Alternatives
The tech industry’s business model thrives on constant churn: new features, fancier designs, and heavier apps — not because they’re essential, but because they keep consumers upgrading. Stripping your phone back to basics is an act of tech self-defense.…...
SpringAI--基于MySQL的持久化对话记忆实现
SpringAI–基于MySQL的持久化对话记忆实现 项目源码 对话记忆官方介绍 SpringAI目前提供了一些将对话保存到不同数据源中的实现,比如: InMemoryChatMemory 基于内存存储CassandraChatMemory 在Cassandra中带有过期时间的持久化存储。Neo4jChatMemory 在Neo4j中没…...
【教学类-34-12】20250509(通义万相)4*3蝴蝶拼图(圆形、三角、正方、半圆的凹凸小块+数字提示+参考图灰色)
背景介绍 制作了四款异形角拼图,初步实现效果 【教学类-34-10】20250503(通义万相)4*3蝴蝶拼图(圆形、三角、正方、半圆的凹凸小块+参考图灰色)-CSDN博客文章浏览阅读1.4k次,点赞46次,收藏15次。【教学类-34-10】20250503(通义万相)4*3蝴蝶拼图(圆形、三角、正方、…...
C++编程语言:标准库:标准库概观(Bjarne Stroustrup)
第30章 标准库概观(Standard-Library Overview) 目录 30.1 引言 30.1.1 标准库设施 30.1.2 设计约束 30.1.3 描述风格 30.2 头文件 30.3 语言支持 30.3.1 对initializer_list的支持 30.3.2 对范围for的支持 30.4 异常处理 30.4.1 异常 30.4.1…...
Springboot+Vue+Mybatis-plus-Maven-Mysql项目部署
目录 VScode 1插件 2快捷键修改 3图标主题设置 4常用设置1 5设置自动换行 6颜色主题 7创建站点 8新建一个html文件 window系统设置 ps 1取色 2测量 3修改单位为像素 4放大图片 5拖动放大之后的图片 6文字大小测量 7测量文字的行高 8矩形选框切图1 9矩形选框…...
【C/C++】C++中noexcept的妙用与性能提升
文章目录 C中noexcept的妙用与性能提升1 什么情况下会抛出异常2 标记noexcept作用3 何时使用noexcept4 无异常行为标记场景5 一句话总结 C中noexcept的妙用与性能提升 在C中,noexcept修饰符用于指示函数不会抛出异常 1 什么情况下会抛出异常 在 C 中,异…...
增强学习(Reinforcement Learning)简介
增强学习(Reinforcement Learning)简介 增强学习是机器学习的一种范式,其核心目标是让智能体(Agent)通过与环境的交互,基于试错机制和延迟奖励反馈,学习如何选择最优动作以最大化长期累积回报。…...
如何优化系统启动时间--基于米尔瑞萨MYD-YG2LX开发板
1.概述 MYD-YG2LX采用瑞萨RZ/G2L作为核心处理器,该处理器搭载双核Cortex-A551.2GHzCortex-M33200MHz处理器,其内部集成高性能3D加速引擎Mail-G31 GPU(500MHz)和视频处理单元(支持H.264硬件编解码),16位的DDR4-1600 / DDR3L-1333内…...
.Net HttpClient 概述
HttpClient 概述 作用 HttpClient是一个用于发送HTTP请求和接收HTTP响应的类。它提供了一种现代化、灵活和强大的方式来与Web服务进行通信。HttpClient类位于System.Net.Http命名空间下,可以通过NuGet包管理器进行安装。 整体理解 HttpClient是应用程序进程中&am…...