var是编译期推断的静态类型,类型固定且零开销;dynamic是运行时解析的动态类型,跳过编译检查但有dlr解析成本,易致运行时崩溃。

var 是编译期推断的静态类型,dynamic 是运行时解析的动态类型——二者根本不在同一机制层级上,混用会导致编译错误或运行时崩溃。
var 声明后类型就固定了,不能改
编译器看到 var x = 42; 就立刻把它当作 int x = 42; 处理,后续任何赋值都必须符合 int 类型规则:
-
x = "hello";→ 编译失败,报错Cannot implicitly convert type 'string' to 'int' -
var list = new List<string>();</string>→list就是List<string></string>,调用list.Add(123)会编译报错 - 没初始化就声明:
var y;→ 直接编译失败,提示Implicitly-typed variables must be initialized
dynamic 跳过所有编译检查,但运行时报错风险高
dynamic 告诉编译器:“别管类型,我 runtime 自己扛”。所以:
-
dynamic z = 100; z = "ok"; z = DateTime.Now;→ 全部通过编译 -
z.NonExistentMethod();→ 编译不拦,但运行时抛RuntimeBinderException -
z.Length在z是string时正常,是int时直接崩 - IDE 不提供智能提示(IntelliSense),因为编译器根本不知道它“此刻”能调什么
性能差异明显:var 零开销,dynamic 有 DLR 解析成本
这是容易被忽略的实际影响点:
-
var完全是编译期行为,生成的 IL 和你手写string s = "a";一模一样,无任何运行时负担 -
dynamic每次成员访问(属性、方法、索引器)都要走 DLR(Dynamic Language Runtime),触发绑定缓存查找、类型检查、委托生成等步骤 - 在循环或高频路径里用
dynamic,比如for (int i = 0; i (<code>obj是dynamic),性能可能比等价的强类型低一个数量级
该用哪个?看变量生命周期和确定性
不是“哪个更高级”,而是“谁更适合当前上下文”:
- 用
var:LINQ 查询返回匿名类型(var user = new { Name = "A", Age = 25 };)、泛型嵌套太长(var dict = new Dictionary<string func bool>>();</string>)、类型一目了然时 - 用
dynamic:对接 JSON.NET 的JObject、调用 COM 对象(如 Excel 互操作)、反射结果需要链式调用(dynamic inst = Activator.CreateInstance(type); inst.Do();)、明确接受运行时异常风险的胶水代码 - 不用
dynamic:业务逻辑主干、DTO 层、配置解析(应优先用强类型模型 +JsonSerializer.Deserialize<t></t>)
真正难处理的不是语法,而是当 dynamic 报出 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException 时,堆栈里看不到原始数据源——你得倒推哪一步的类型假设错了。这点在调试生产环境 JSON 数据结构漂移时尤其痛苦。











