【问题标题】:Why does adding primitive struct to a List not require the new keyword. Whereas adding non-primitive struct to List require the new keyword? - C# [closed]为什么将原始结构添加到 List 不需要 new 关键字。而将非原始结构添加到 List 需要 new 关键字? - C# [关闭]
【发布时间】:2020-12-25 04:24:57
【问题描述】:

将原语struct(例如int)添加到List

int i=10;
List<int> list=new List<int>();
list.Add(i);

对比: 将非原始struct(例如KeyValuePair&lt;int,int&gt;)添加到列表中:

List<KeyValuePair<int, int>> list = new List<KeyValuePair<int, int>>();
list.Add(new KeyValuePair<int,int>(10,20));

在将int struct 添加到list 时,我们不需要使用new 关键字。但是在将KeyValuePair struct 添加到列表时,我们需要使用new 关键字。

我的意思是说,下面的说法是无效的:

list.Add(new int(10)); //invalid statement

虽然intKeyValuePair 都是结构体,但它们的行为不同——在使用前不需要实例化(就用户而言)。而另一个需要在使用前进行实例化。

为什么我们不能这样做:

list.Add(KeyValuePair<int,int>(10,20)) //omit the new keyword, as we were doing with an int

来自 C/C++ 背景,new 关键字在 C# 中究竟做了什么? 它只是实例化底层数据类型(我们不确定实例化的数据类型是位于堆栈还是堆上)。或者,我们确定使用 new 关键字会在堆上分配内存(就像在 C++ 中那样)?

【问题讨论】:

  • 阅读我对这个问题的回答stackoverflow.com/questions/65418824/…。它不会直接回答您的问题,但应该使答案显而易见
  • "在将 int 结构体添加到列表时,我们不需要使用 new 关键字。但是在将 KeyValuePair 结构体添加到列表时,我们需要使用 new 关键字" -- 那是完全错误的。从根本上说,你的问题是错误的。您声称以某种方式根本不同的示例,根本没有什么不同。 System.Int32 确实没有任何带参数的构造函数。但是你当然可以写new int()。 ...
  • ... 更重要的是,您还可以将变量命名为i,将其声明为KeyValuePair&lt;int, int&gt;,然后使用与第一个例子,即list.Add(i);没有区别,所以问为什么有区别是没有意义的。
  • 而且,就其价值而言,当一个类型具有 literal 表示时,您可以将文字视为 new T (LiteralOfT) 的“const”版本。像int i = 10; 这样的表达式非常接近int i = new int(10)new 关键字从托管堆分配内存,然后为引用类型运行构造函数,就像 C++ 一样。值类型的 new 关键字只是运行构造函数而不分配内存。然后将构造对象的结果值复制到变量中
  • 这个问题很有趣,即使写得不好。为什么不使用new(或default())关键字就可以初始化某些类型(intstring、...)?答案归结为文字(和常量表达式(你可以做int x = (int)5.5))的存在

标签: c# struct heap-memory instantiation stack-memory


【解决方案1】:

new 关键字在 C# 中究竟做了什么?

全部列出here。与这个问题最相关的是“构造函数调用”。结构和类都有构造函数,构造函数创建结构和类的实例。

当你这样做时:

new KeyValuePair<int,int>(10,20)

你打电话给this constructor

intInt32 结构的别名,它没有接受int 类型参数的构造函数。这就是你做不到的原因:

new int(10)

请注意,调用构造函数并不是创建结构实例的唯一方法。您还可以执行以下操作:

var defaultKVP = default(KeyValuePair<int, int>); // gets the default value of the type KeyValuePair<int, int>
// defaultKVP is an instance of KeyValuePair<int, int>! It's not null! Structs can't be null :)

结构的default value 是通过将其所有值类型字段设置为其默认值并将引用类型字段设置为空来定义的。

为什么像10 这样的整数文字是结构Int32 的一个实例,这就是编译器的魔力。规范是这么说的,所以就是这样实现的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    • 1970-01-01
    • 2016-04-05
    相关资源
    最近更新 更多