🔥关注墨瑾轩,带你探索编程的奥秘!🚀
🔥超萌技术攻略,轻松晋级编程高手🚀
🔥技术宝库已备好,就等你来挖掘🚀
🔥订阅墨瑾轩,智趣学习不孤单🚀
🔥即刻启航,编程之旅更有趣🚀
你的代码还在和“类型检查”较劲吗?调用方法像“开盲盒”?运行时突然炸出一堆错误?——这不是“代码诅咒”,是你的动态类型在“躺平”!今天就教你在C#中打造“类型变形金刚”,从基础到实战全搞定!(掏出小本本,准备抄代码!)
Step1:动态类型入门——“盲盒变量”初体验
问题:# 如何让变量像“变形金刚”一样随时变身?
// 📄 动态类型基础(DynamicDemo.cs)
using System;
class Program {
static void Main() {
// 🌟 1️⃣ 声明dynamic变量(盲盒已开!)
dynamic magicBox = 42; // 初始类型:int
Console.WriteLine($"类型:{magicBox.GetType().Name}"); // 输出:Int32
// 🌟 2️⃣ 动态变身(类型随时变!)
magicBox = "Hello, Dynamic!"; // 新类型:string
Console.WriteLine($"类型:{magicBox.GetType().Name}"); // 输出:String
// 🌟 3️⃣ 玩转类型(像变魔术!)
magicBox = new { Name = "C#", Age = 20 }; // 匿名类型
Console.WriteLine($"名字:{magicBox.Name}"); // 输出:C#
}
}
/*
* 🔮 关键点:
* 1️⃣ dynamic变量像“盲盒”,类型随赋值动态变化
* 2️⃣ 编译时不管,运行时才确定类型
*/
Step2:运行时操作——“调用不存在的成员?试试看!”
问题:# 如何让代码像“开盲盒”一样调用未知方法?
// 📄 运行时调用(RuntimeDemo.cs)
class Program {
static void Main() {
// 🌟 1️⃣ 创建动态对象(ExpandoObject)
dynamic expando = new System.Dynamic.ExpandoObject();
// 🌟 2️⃣ 动态添加属性和方法
expando.Name = "Alice";
expando.SayHello = new Action(() => Console.WriteLine($"Hello, {expando.Name}!"));
// 🌟 3️⃣ 调用动态方法(运行时才检查!)
expando.SayHello(); // 输出:Hello, Alice!
// 🌟 4️⃣ 调用不存在的成员?运行时报错!
try {
expando.NonExistent(); // 报错!
} catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ex) {
Console.WriteLine($"运行时炸了!错误:{ex.Message}");
}
}
}
/*
* 🔮 关键点:
* 1️⃣ 动态对象支持“边写边玩”
* 2️⃣ 编译时不管,但运行时要小心!
*/
Step3:动态类型 vs object——“谁才是类型之王?”
问题:# 为什么dynamic比object更“野”?
// 📄 对比实验(TypeComparison.cs)
class Program {
static void Main() {
// 🌟 1️⃣ object变量:严格检查
object obj = "I'm a string";
// obj.ToUpper(); // 编译报错!object没有ToUpper
// 🌟 2️⃣ dynamic变量:运行时才检查
dynamic dyn = "I'm a dynamic string";
Console.WriteLine(dyn.ToUpper()); // 输出:I'M A DYNAMIC STRING
// 🌟 3️⃣ 类型转换对比
int number = (int)dyn; // object转int会炸!
// int number = (int)obj; → 运行时异常!
}
}
/*
* 🔮 关键点:
* 1️⃣ object:编译时检查,类型安全但死板
* 2️⃣ dynamic:运行时检查,灵活但危险
*/
Step4:动态类型实战——“JSON解析超能力”
问题:# 如何用dynamic秒变JSON解析大师?
// 📄 JSON解析(JsonParsing.cs)
using System;
using Newtonsoft.Json;
class Program {
static void Main() {
// 🌟 1️⃣ JSON字符串(模拟API返回)
string json = @"{
'Name': 'Dynamic Hero',
'Skills': ['TypeCheck', 'RunTimeMagic'],
'Level': 100
}";
// 🌟 2️⃣ 动态解析(自动转类型!)
dynamic hero = JsonConvert.DeserializeObject(json);
// 🌟 3️⃣ 直接访问属性
Console.WriteLine($"名字:{hero.Name}"); // 输出:Dynamic Hero
Console.WriteLine($"技能数量:{hero.Skills.Count}"); // 输出:2
// 🌟 4️⃣ 安全访问(防止炸裂)
if (hero.Skills != null) {
foreach (var skill in hero.Skills) {
Console.WriteLine($"技能:{skill}");
}
}
}
}
/*
* 🔮 关键点:
* 1️⃣ 动态解析JSON,无需定义实体类
* 2️⃣ 适合结构未知的API数据
*/
Step5:性能优化——“动态类型不卡顿的秘诀”
问题:# 为什么我的代码用了dynamic会变“龟速”?
// 📄 性能优化(PerformanceTips.cs)
class Program {
static void Main() {
// 🌟 1️⃣ 避免高频动态操作
// ❌ 错误用法:循环内用dynamic
for (int i = 0; i < 1000000; i++) {
dynamic num = i;
// ...
}
// 🌟 2️⃣ 转静态类型(提升速度)
dynamic data = GetDynamicData();
int safeNum = (int)data.Number; // 强制转为静态类型
// 🌟 3️⃣ 与DLR配合(背后有大神!)
// DLR(动态语言运行时)会缓存类型信息,减少重复解析
}
static dynamic GetDynamicData() {
return new { Number = 42 };
}
}
/*
* 🔮 关键点:
* 1️⃣ 动态类型比静态类型慢3-5倍
* 2️⃣ 高频操作转静态类型!
*/
隐藏技巧:动态类型与反射——“谁才是偷懒神器?”
问题:# 为什么dynamic比反射更“懒”?
// 📄 反射 vs dynamic(ReflectionDemo.cs)
class Program {
static void Main() {
// 🌟 1️⃣ 反射调用方法(代码又臭又长)
var obj = new Calculator();
var method = obj.GetType().GetMethod("Add");
var result = (int)method.Invoke(obj, new object[] { 3, 5 }); // 输出:8
// 🌟 2️⃣ dynamic调用(代码优雅!)
dynamic dynCalc = new Calculator();
int dynResult = dynCalc.Add(3, 5); // 输出:8
}
}
class Calculator {
public int Add(int a, int b) => a + b;
}
/*
* 🔮 关键点:
* 1️⃣ dynamic比反射代码更简洁
* 2️⃣ DLR底层优化,性能更高!
*/
代码全公开:从基础到实战的完整流程
// 📄 动态类型工具箱(DynamicToolkit.cs)
using System;
using System.Dynamic;
using Newtonsoft.Json;
public static class DynamicToolkit {
// 🔥 1️⃣ 动态JSON解析
public static dynamic ParseJson(string json) => JsonConvert.DeserializeObject(json);
// 🔥 2️⃣ 安全访问动态属性
public static T GetSafeValue<T>(dynamic obj, string propName, T defaultValue) {
try {
return obj[propName];
} catch {
return defaultValue;
}
}
// 🔥 3️⃣ 动态对象扩展(ExpandoObject)
public static dynamic CreateDynamicObject(params (string, object)[] properties) {
dynamic expando = new ExpandoObject();
foreach (var (key, value) in properties) {
((IDictionary<string, object>)expando)[key] = value;
}
return expando;
}
}
/*
* 🔮 使用示例:
* dynamic user = DynamicToolkit.ParseJson(jsonData);
* int age = DynamicToolkit.GetSafeValue<int>(user, "Age", 18);
*/
恭喜!你已经掌握了C#动态类型的“五步超能力”!从基础到实战,每一步都像给代码装上了“变形金刚”!记住:
1️⃣ dynamic是“运行时盲盒”:编译不管,运行时才确定!
2️⃣ object是“乖乖类型”:严格检查,但死板!
3️⃣ JSON解析+反射简化:动态类型才是偷懒神器!