【问题标题】:Initializer syntax vs. parameterless constructor syntax初始化器语法与无参数构造器语法
【发布时间】:2019-05-15 18:57:00
【问题描述】:

实例化新的空“列表”样式对象有两种替代样式:

var list = new SomeListType<int>();

var list = new SomeListType<int> { };

第一个依赖于允许基本构造函数设置对象,第二个似乎也隐式依赖于构造函数,但也指定了一个空的初始化列表。

(初始化器列表故意留空,说明它在某些情况下是否更易读或更清晰。)

这两种方法在实际或功能上有什么区别吗?

(注意——SomeListType 可以是任何可以像这样构造的东西——例如标准的List&lt;T&gt; 或一些自定义类。仅以int 为例)。

【问题讨论】:

  • 选择任何你觉得更易读的东西。没有其他区别。两者都将使用默认构造函数。后者将为{} 中的每个项目调用Add。因为它是空的,所以没有区别。
  • 提示:如果您想查看两行代码之间的真正区别:sharplab.io - here's this example - 查看 IL 结果(注意 AB 是除了名称相同),或者 C# 结果,如果它是具有有趣的 C# 生成代码(异步、表达式、迭代器等)的非平凡的东西

标签: c# list initializer


【解决方案1】:

即使生成的 IL 代码对于这两个选项都是相同的:

newobj instance void class Namespace.SomeListType`1<int32>::.ctor() 

所以根本没有功能上的区别。

【讨论】:

    【解决方案2】:

    你写的两行代码编译结果是一样的。不同之处在于,在第二个版本中,您可以通过在花括号中添加项目来初始化列表(前提是您的列表实现了ICollection&lt;T&gt; 接口或提供了相应的Add 方法:

    var list = new SomeListType<int> { 1, 2, 3, 4 };
    

    【讨论】:

    • 该类型只需要实现IEnumerable acc。到specs
    • @MarcGravell:当然可以,但是 Sefe 说过需要实现ICollection&lt;T&gt;
    • 为什么需要实现 IEnumerable 来添加项目? (我知道它必须,但为什么)
    • @Magnus:因为如果你使用{item1,item2},这就是语言期望支持语法糖功能自动调用Add的最低限度。它需要是一个IEnumerable 并且它需要有一个Add 方法(可以是一个扩展)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 2016-04-19
    相关资源
    最近更新 更多