为什么将原始结构添加到 List 不需要 new 关键字。而向 List 添加非原始结构需要 new 关键字? - C#

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#

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

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

对战: 将非原始 struct(例如 KeyValuePair<int,int>)添加到列表中:

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# 中的确切作用是什么? 它是否只是实例化底层数据类型(而且我们不确定实例化的数据类型是位于Stack还是Heap)。或者,我们确定使用 new 关键字会在堆上分配内存(就像在 C++ 中一样)吗?

what does the new keyword exactly do in 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 的一个实例,是因为编译器的魔法。规范是这么说的,所以它是这样实现的。