【发布时间】:2018-02-13 21:00:42
【问题描述】:
过去我使用完整的初始化语法来初始化数组:
int[] arr = new int[1] { 1 };
但是一旦我发现我不需要在初始化期间指定类型,我就停止这样做了:
int[] arr = { 1 };
我最近再次查看了锯齿状数组,发现这种语法有一个非常特殊的问题:
int[][] jag = { { 1, 2 }, { 3 } };
上面的代码无效,这让我很困惑。此外,这种语法很好:
int[][] jag = { new []{ 1, 2 }, new []{ 3 } };
显然,这里唯一的区别是“new”关键字。通常,在其他语言中,“new”关键字表示变量将成为引用类型,但在 C# 中,数组始终是引用类型,因此实际上没有必要为数组指定“new”。有谁知道为什么我需要在这个锯齿状数组初始化中指定它?这是一个错误,还是只是一个未实现的编译器功能?
【问题讨论】:
-
但在 C# 中,数组始终是引用类型,因此确实没有必要为数组指定“新” 这不符合。这不是一个错误,它只是不是他们内置在语言中的一点编译器糖。将来可能会或可能不会添加它。您可以尝试在 GitHub 上请求它,但由于锯齿状数组(根据我的经验)很少见,我怀疑有多少行动......
-
"new" 并不表示类型是引用类型。由于这是错误的,因此您基于此错误前提得出的任何结论都不符合逻辑。
int x = new int();是一种完全合法的,虽然很奇怪,写int x = 0;的方式。new表示正在分配新的存储空间。对于值类型,该存储是从临时池中分配出来的,然后复制,对于引用类型,该存储是从长期池中分配出来的。 -
另一个原因是嵌套大括号语法
{ { ... }, { ... }, ... }是为IList类型调用.Add的语法糖。System.Array没有Add- 以及“本机”多维数组:docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/… -
请注意,如果 C# 编译器和 jitter 能够证明这样做是安全的,则允许它们复制省略。比如你有
S s = new S(123);对应一个值类型S,规范的要求是分配新的存储,把新的存储传递给构造函数,构造函数运行,然后值类型被复制值s。 练习:在什么情况下编译器可以合法地将s的存储传递给构造函数并跳过alloc-and-copy?什么情况下不能? -
@Will: 没有故意的打击。我只是在陈述事实。全文本交流中存在一种偏见,这使得事实陈述听起来像是批评,但它们只是事实。
标签: c# arrays jagged-arrays