C#中的dynamic与var:看似相似却判然不同

打印 上一主题 下一主题

主题 1982|帖子 1982|积分 5946

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x


在C#编程的天下里,var和dynamic这两个关键字经常让初学者感到困惑。它们看起来都在界说变量时省略了显式类型声明,但实际上它们的工作方式和应用场景有着天壤之别。今天,让我们一起揭开这两个关键字的神秘面纱。
var:编译时的类型推断

var关键字是在C# 3.0(2007年)引入的,它的核心特性是隐式类型化,但这并不意味着它是弱类型的。相反,使用var声明的变量在编译时就会被确定为一个具体的强类型。
  1. var name = "byteflow";   // 编译器将name推断为string类型
  2. var age = 25;          // 编译器将age推断为int类型
复制代码
编译后,上面的代码等同于:
  1. string name = "byteflow";
  2. int age = 25;
复制代码
一旦类型确定,就不能再改变:
  1. var number = 10;
  2. // number = "ten";  // 编译错误!int类型不能赋值为string
复制代码
dynamic:运行时的类型解析

相比之下,dynamic是在C# 4.0(2010年)引入的,它代表的是一种完全不同的编程范式。使用dynamic关键字声明的变量会绕过编译时类型查抄,全部的类型查抄推迟到运行时举行。
  1. dynamic value = 100;
  2. value = "现在我是字符串";  // 完全合法!
  3. value = new List<int>();  // 也没问题!
复制代码
这意味着你可以在运行时改变变量的类型,也可以调用在编译时无法确定的方法:
  1. dynamic obj = GetSomeObject();  // 我们不确定返回什么类型
  2. obj.DoSomething();              // 编译通过,运行时决定能否调用
复制代码
关键区别:一张图看懂

特性vardynamic类型确定时机编译时运行时智能提示完全支持不支持可作为返回类型不可以可以可改变类型不可以可以性能影响无有开销类型安全安全不安全 何时使用var?

var最得当的场景包括:

  • 进步代码可读性,特殊是处理长类型名时:
    1. var dictionary = new Dictionary<string, List<Customer>>();
    2. // 比 Dictionary<string, List<Customer>> dictionary = new Dictionary<string, List<Customer>>(); 更简洁
    复制代码
  • 处理匿名类型
    1. var person = new { Name = "byteflow", Age = 25 };
    复制代码
  • LINQ查询结果
    1. var results = from c in customers where c.City == "北京" select c;
    复制代码
何时使用dynamic?

dynamic则在以下场景发挥作用:

  • 与动态语言或COM互操作
    1. dynamic excel = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
    2. excel.Visible = true;
    复制代码
  • 处理JSON、XML等数据
    1. dynamic jsonData = JsonConvert.DeserializeObject(jsonString);
    2. string name = jsonData.Name;  // 无需预先知道JSON结构
    复制代码
  • 替换复杂的反射
    1. dynamic instance = Activator.CreateInstance(someType);
    2. instance.SomeMethod();  // 比反射代码简洁
    复制代码
实战示例:同一个问题,两种解法

假设我们需要处理一个对象并打印其属性:
使用var的方式(编译时安全):
  1. void ProcessObject(Person person)
  2. {
  3.     var name = person.Name;  // 编译器知道这是string类型
  4.     var age = person.Age;    // 编译器知道这是int类型
  5.     Console.WriteLine($"{name}今年{age}岁");
  6. }
复制代码
使用dynamic的方式(更机动但风险更高):
  1. void ProcessAnyObject(dynamic obj)
  2. {
  3.     try {
  4.         var info = $"{obj.Name}今年{obj.Age}岁";
  5.         Console.WriteLine(info);
  6.     }
  7.     catch (RuntimeBinderException) {
  8.         Console.WriteLine("对象不包含所需属性");
  9.     }
  10. }
复制代码
结语:衡量与选择

var和dynamic代表了C#语言的两种不同设计理念:一个是保证类型安全但提供语法糖简化代码;另一个是提供动态特性以增强机动性。
作为一条经验法则:默认情况下使用var以得到简便性和性能,只在真正需要动态行为时才使用dynamic
记住,简便的代码固然重要,但类型安全往往能帮你克制许多难以调试的运行时错误。在选择两者之间,需要根据具体场景衡量得失。
希望这篇文章能资助你明白这两个关键字的本质区别,在C#编程中做出更明智的选择!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

石小疯

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表