You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6中两种C#对象创建写法的差异及优劣势对比

核心结论

两种写法不存在运行时层面的本质区别,编译后生成的IL代码完全一致,没有任何性能差异。二者的区别仅存在于C#语法层面,属于不同版本推出的语法糖,适用场景有少量差异。

性能表现

两种写法的编译结果完全相同:最终都是在托管堆分配List<string>实例,在栈上持有对应类型的引用,不会产生任何额外的执行开销或者内存占用,运行时表现100%一致,不存在谁快谁慢的问题。

语法规则差异

两种写法依托不同的C#语法特性实现,规则边界有明显区别:

  • 写法1 var list = new List<string>(); 用的是C# 3.0推出的隐式局部变量特性:编译器通过右侧初始化表达式的类型,自动推断局部变量list的静态类型为List<string>。注意var只能用于声明方法内的局部变量,不能用来定义类的字段、属性,也不能用于方法签名的参数、返回值位置。
  • 写法2 List<string> list = new(); 用的是C# 9.0推出的目标类型new表达式特性:编译器通过左侧显式声明的变量类型(或其他赋值目标的类型,比如方法参数、返回值、成员初始化位),自动推断new关键字要实例化的目标类型为List<string>。这个特性没有使用位置限制,只要赋值目标有明确、可实例化的具体类型(不能是接口、抽象类)就可以正常使用。

额外提一个编译层面的约束:你不能写var list = new();,这种写法左右两侧都没有给编译器提供明确的类型信息,会直接编译报错。

适用场景与优劣势对比

两种写法在局部变量声明、且变量类型和实例化类型完全一致的场景下完全等价,选哪个只需要遵循团队的编码规范即可,没有绝对的优劣。二者各自有独有的适用场景:

  • 写法1(var+完整new表达式)的独有场景:
    • 配合匿名类型使用,比如LINQ查询生成的匿名类型结果,因为匿名类型没有可以手动书写的类型名,只能用var接收,比如var queryResult = list.Select(x => new { x.Id, x.Name }).ToList();
    • 当你不需要显式修改变量类型,希望直接以实例化的具体类型作为变量类型,且类型名不长的时候,写法更符合多数C#开发者的长期书写习惯。
  • 写法2(显式类型声明+目标类型new)的独有优势:
    • 当变量类型是长泛型、嵌套泛型的时候,可以避免左右两侧重复书写一长串相同的类型名,大幅减少冗余代码,比如Dictionary<string, List<(int UserId, string UserName)>> cache = new();比左右重复写一遍长泛型要简洁很多。
    • 可以用于类的字段、属性初始化场景,这是var做不到的,比如你可以在类里写public List<string> Tags { get; init; } = new();,但不能用var声明这个属性。
    • 如果你需要把变量声明为实例类型的基类,只要new的目标类型和变量类型一致就可以正常使用,不需要重复写类型名。

注意:如果你要把变量声明为接口/抽象父类类型,而实例化的是对应的实现类/派生类,两种写法都不能省略类型名:比如你要声明IList<string> list = new List<string>();,这时候没法用new()简化,因为编译器会尝试直接实例化接口IList<string>,会直接编译报错。

内容的提问来源于stack exchange,提问作者user19187727

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 19:30:17