📅 Day 21:动态类型与动态语言运行时(Dynamic Types & DLR)

✅ 学习目标:

  • 理解什么是 dynamic 类型
  • 掌握 dynamicobject 的区别;
  • 理解 DLR(Dynamic Language Runtime) 的作用;
  • 学会使用 dynamic 简化反射、COM 互操作等场景;
  • 理解 ExpandoObjectDynamicObject 的用法;
  • 编写一个基于 dynamic 的 JSON 解析器或脚本执行器示例。

🧠 一、什么是 dynamic 类型?

在 C# 中,dynamic 是一种特殊的类型,它绕过了编译时的类型检查,将类型解析延迟到运行时进行。

示例:

dynamic x = 10;
x = "Hello";       // 合法
x = new Person();  // 合法

⚠️ 编译时不检查成员是否存在,运行时才会抛出异常。


🔁 二、dynamic vs object

特性objectdynamic
编译时类型检查
运行时解析
性能更快稍慢(需 DLR 解析)
适合场景多态、泛型反射简化、脚本交互

💡 三、DLR(Dynamic Language Runtime)

DLR(动态语言运行时) 是 .NET Framework 4 引入的一个子系统,用于支持动态语言(如 Python、Ruby)在 .NET 平台上的运行。它也支撑了 C# 中的 dynamic 功能。

DLR 的核心功能包括:

  • 运行时绑定(Runtime Binding)
  • 动态对象解析(如 COM 对象、Python 对象)
  • 缓存机制优化性能

🧩 四、常见使用场景

场景 1:简化反射调用

传统反射方式:

object obj = GetSomeObject();
MethodInfo method = obj.GetType().GetMethod("DoWork");
method.Invoke(obj, null);

使用 dynamic

dynamic obj = GetSomeObject();
obj.DoWork();  // 编译不报错,运行时自动解析

场景 2:COM 互操作(如 Excel 自动化)

Type excelType = Type.GetTypeFromProgID("Excel.Application");
dynamic excel = Activator.CreateInstance(excelType);
excel.Visible = true;
excel.Workbooks.Add();

场景 3:处理不确定结构的数据(如 JSON)

string json = "{\"Name\":\"张三\",\"Age\":25}";
dynamic data = JsonSerializer.Deserialize<JsonElement>(json);Console.WriteLine(data.Name);
Console.WriteLine(data.Age);

🧱 五、System.Dynamic 命名空间

C# 提供了几个类来帮助你创建自定义的动态对象:

1. ExpandoObject

表示一个可以在运行时动态添加和删除成员的对象。

dynamic person = new ExpandoObject();
person.Name = "李四";
person.Age = 30;person.SayHello = new Action(() => Console.WriteLine("你好!"));person.SayHello();  // 输出:你好!

2. DynamicObject

你可以继承此类并重写其方法来自定义动态行为。

public class MyDynamic : DynamicObject
{private Dictionary<string, object> _properties = new();public override bool TrySetMember(SetMemberBinder binder, object value){_properties[binder.Name] = value;return true;}public override bool TryGetMember(GetMemberBinder binder, out object result){return _properties.TryGetValue(binder.Name, out result);}
}// 使用
dynamic obj = new MyDynamic();
obj.Name = "王五";
Console.WriteLine(obj.Name);  // 输出:王五

🧪 六、动态表达式树(Expression Trees)

虽然 dynamic 很方便,但如果你需要高性能的动态行为,推荐使用 Expression<TDelegate> 构建动态委托。

ParameterExpression param = Expression.Parameter(typeof(int), "x");
Expression body = Expression.Multiply(param, param);
Func<int, int> square = Expression.Lambda<Func<int, int>>(body, param).Compile();Console.WriteLine(square(5));  // 输出:25

💪 实战练习:构建一个简单的动态 JSON 解析器

功能要求:

  • 从 API 获取 JSON 数据;
  • 使用 dynamic 解析并输出字段;
  • 支持嵌套属性访问。
示例代码:
using System;
using System.Net.Http;
using System.Text.Json;class Program
{static async Task Main(){using HttpClient client = new HttpClient();string json = await client.GetStringAsync("https://jsonplaceholder.typicode.com/users/1");dynamic user = JsonSerializer.Deserialize<JsonElement>(json);Console.WriteLine("用户ID:" + user.id);Console.WriteLine("用户名:" + user.username);Console.WriteLine("地址城市:" + user.address.city);}
}

⚠️ 七、注意事项与最佳实践

建议说明
避免滥用 dynamic它牺牲了编译时安全性和 IDE 智能提示
不要用于公共 API应该优先使用接口或泛型
谨慎用于性能关键路径DLR 有额外开销
在反射、JSON、COM 场景中合理使用可显著提升开发效率

📝 小结

今天你学会了:

  • dynamic 类型的基本概念及其与 object 的区别;
  • 了解了 DLR(动态语言运行时) 的作用;
  • 掌握了如何使用 dynamic 简化反射、COM 互操作、JSON 解析等场景;
  • 学会使用 ExpandoObjectDynamicObject 创建自定义动态对象;
  • 编写了一个基于 dynamic 的 JSON 解析器示例;
  • 了解了 dynamic 的性能影响及适用场景。

dynamic 是 C# 中非常强大的工具,尤其适用于与外部系统交互、快速原型开发等场景。但在大型项目中应谨慎使用以确保可维护性。


🧩 下一步学习方向(Day 22)

明天我们将进入一个新的主题 —— LINQ(Language Integrated Query)基础与进阶,你将学会如何使用 LINQ 查询集合、数据库、XML,并掌握查询语法与方法语法的区别。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88228.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88228.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/88228.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode-3085.成为K字符串需要删除的最小字符串数

题目描述 解题思路 这题不难想到需要统计每个字母的出现频率&#xff0c;一共有26个字母&#xff0c;故cnt数组有26维。我们可以枚举其中一种作为「删除操作结束后出现频率最低的字符」&#xff0c;将其设置为 c&#xff0c;那么所有频率小于 c 的字符都会被删除&#xff0c;所…

Android 中 解析 XML 文件的几种方式

在 Android 开发中,解析 XML 文件有多种方式,每种方式都有其特点和适用场景。常见的 XML 解析方式有 DOM 解析、SAX 解析 和 XmlPullParser 解析。 一、xml 文件及数据类 1、xml 文件 将测试用 book.xml 文件放在项目的 app/src/main/assets 目录下,文件内容如下:<lib…

python里的abc库是什么东西

Python 中的 ABC&#xff1a;为什么你需要抽象基类&#xff1f;告别“假鸭子”&#xff0c;拥抱真抽象&#xff01; 你是不是经常在 Python 项目中感到困惑&#xff1a;我定义了一个类&#xff0c;希望它能被其他类继承并实现某些特定功能&#xff0c;但又不想它被直接实例化&…

设计模式精讲 Day 9:装饰器模式(Decorator Pattern)

【设计模式精讲 Day 9】装饰器模式&#xff08;Decorator Pattern&#xff09; 文章内容 在软件开发中&#xff0c;灵活扩展功能是提升系统可维护性和可复用性的关键。装饰器模式作为一种结构型设计模式&#xff0c;为对象动态地添加职责&#xff0c;而无需通过继承来实现。它…

浏览器无法访问:Nginx下的基于域名的虚拟主机

检查步骤如下&#xff1a; 1、nginx -t &#xff0c;检查配置文件是否有语法错误 [root89 ~]# nginx -t nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok nginx: configuration file /opt/nginx/conf/nginx.conf test is successful # 可以看到 配置…

【appium】6.appium遇到的问题

1.appium-python-client 修改版本1.5 为5.1.1,后执行python程序时&#xff0c;提示&#xff1a; raise TypeError( TypeError: missing 1 required keyword-only argument: options (instance of driver options.Options class) 你遇到的错误&#xff1a; TypeError: missing…

C++法则3:使用拷贝和交换的赋值运算符自动就是异常安全的,且能正确处理自赋值。

C法则3&#xff1a;使用拷贝和交换的赋值运算符自动就是异常安全的&#xff0c;且能正确处理自赋值。 这条法则强调了使用"拷贝和交换"(Copy-and-Swap)惯用法来实现赋值运算符()的优点&#xff1a; 关键点 异常安全&#xff1a;拷贝和交换方法天然提供了强异常安全…

纯血HarmonyOS5 打造小游戏实践:扫雷(附源文件)

鸿蒙扫雷游戏的核心架构设计 鸿蒙OS扫雷游戏采用了MVC&#xff08;模型-视图-控制器&#xff09;的架构思想&#xff0c;将游戏逻辑与UI展示分离&#xff0c;使得代码结构清晰且易于维护。整个游戏由以下几个核心部分构成&#xff1a; 数据模型设计 游戏的基础数据模型是Cel…

Linux C语言的opendir如何获取目录下的隐藏文件

在 Linux 文件系统中&#xff0c;所谓隐藏文件是文件名以 . 开头的文件&#xff08;例如 .bashrc、.git、.config 等&#xff09;。 在编程层面&#xff0c;opendir readdir 并不会自动排除隐藏文件。 只要你不在代码中手动过滤&#xff0c;readdir 会把目录下所有文件&#…

母线槽接头过热隐患难防?在线测温方案实时守护电力安全

近年来&#xff0c;由于各种设备对电力的大力需求&#xff0c;并有逐年增加的趋势&#xff0c;传统电路接线方式在施工时越来越力不从心。系统一旦定型&#xff0c;后续想要简化变更更是难上加难。母线槽方案因此兴起&#xff0c;凭借多点连接&#xff08;接头、插接头、插接箱…

Windows本地部署wordpress

一、下载wordpress 地址&#xff1a;Download – WordPress.org 下载后解压出来 二、下载小皮面板 地址&#xff1a;Windows版phpstudy下载 - 小皮面板(phpstudy) 下载后安装 三、打开小皮面板&#xff0c;安装对应内置应用 1、MySQL8&#xff08;注意要是8版本,卸载其他版本…

Android 性能优化

一、Android中检测性能工具 Profiler —— 使用Profiler的CPU分析功能。 Method Tracing ———— 通过该方法,我们可以记录应用运行过程中的方法调用情况,包括每个方法的执行时间、调用次数等。 Systrace 是Android平台提供的一款工具,用于记录短期内的设备活动。 Systra…

图片压缩工具 | Electron应用配合 commander 提供命令行调用功能

OPEN-IMAGE-TINY&#xff0c;一个基于 Electron VUE3 的图片压缩工具&#xff0c;项目开源地址&#xff1a;https://github.com/0604hx/open-image-tiny 功能描述 应用程序的命令行调用功能允许用户通过终端&#xff08;如Windows的CMD/PowerShell或Linux/macOS的Terminal&am…

Linux》》Shell脚本 基本语法

执行脚本的三种方式 查找变量的过程 变量引用的顺序》》先从当前进程查询变量&#xff0c;如果当前进程没有此变量&#xff0c;默认去父进程查找这个变量。如果查找到则返回&#xff0c;否则一直查找到 祖宗&#xff08;PID为1&#xff09;&#xff0c;还没有&#xff0c;则就…

C#.VB.NET多线程,多用户下独立锁和全局锁的区别

以下代码,每个客户端都分配了一个锁吗? 用户WebSocket信息类Public Class UserWebSocketInfoPublic Property SessionID As StringPublic Property WebSocket As WebSocketPublic Property LastResponseTime As DateTimePublic Property PendingHeartbeatCount As IntegerPubl…

无人机加速器模块技术解析

一、加速器模块的运行方式 1. 传感器数据采集与融合 加速度计核心作用&#xff1a;测量三维线性加速度&#xff08;X/Y/Z轴&#xff09;&#xff0c;结合陀螺仪&#xff08;角速度&#xff09;和磁力计&#xff08;方向&#xff09;构成九轴姿态传感器&#xff0c;实时输出…

用html实现数字生命

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>数学粒子动画</title><style>body {mar…

SQLite3 在嵌入式系统中的应用指南

SQLite3 在嵌入式系统中的应用指南 一、嵌入式系统中 SQLite3 的优势 SQLite3 是嵌入式系统的理想数据库解决方案&#xff0c;具有以下核心优势&#xff1a; 特性嵌入式系统价值典型指标轻量级适合资源受限环境库大小&#xff1a;500-700KB零配置无需数据库管理员开箱即用无…

通义大模型与现有企业系统集成实战《CRM案例分析与安全最佳实践》

1. 集成架构设计 &#xff08;1&#xff09;混合部署架构演进 #mermaid-svg-eW4YPoU2fdbnT4xp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-eW4YPoU2fdbnT4xp .error-icon{fill:#552222;}#mermaid-svg-eW4YPoU2f…

leetcode:746. 使用最小花费爬楼梯

学习要点 动态规划正着推动态规划倒着推理解递归在动态规划与纯递归的类比分析中体会两者各自的特点 题目链接 746. 使用最小花费爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 题目描述 解法1&#xff1a;动态规划倒着推 // dp[i]--->从第i阶楼梯到达楼顶最小花费int…