【发布时间】:2020-12-25 04:24:57
【问题描述】:
将原语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
虽然int 和KeyValuePair 都是结构体,但它们的行为不同——在使用前不需要实例化(就用户而言)。而另一个需要在使用前进行实例化。
为什么我们不能这样做:
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<int, int>,然后使用与第一个例子,即list.Add(i);。 没有区别,所以问为什么有区别是没有意义的。 -
而且,就其价值而言,当一个类型具有 literal 表示时,您可以将文字视为
new T (LiteralOfT)的“const”版本。像int i = 10;这样的表达式非常接近int i = new int(10)。new关键字从托管堆分配内存,然后为引用类型运行构造函数,就像 C++ 一样。值类型的new关键字只是运行构造函数而不分配内存。然后将构造对象的结果值复制到变量中 -
这个问题很有趣,即使写得不好。为什么不使用
new(或default())关键字就可以初始化某些类型(int、string、...)?答案归结为文字(和常量表达式(你可以做int x = (int)5.5))的存在
标签: c# struct heap-memory instantiation stack-memory