欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 旅游 > 跟着AI学习C# Day21

跟着AI学习C# Day21

2025/6/24 2:07:29 来源:https://blog.csdn.net/qq_35151545/article/details/148753730  浏览:    关键词:跟着AI学习C# Day21

📅 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,并掌握查询语法与方法语法的区别。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词