【问题标题】:How array get created?如何创建数组?
【发布时间】:2019-06-03 00:33:58
【问题描述】:

创建数组几乎是编程中最常见和最简单的任务,但在我深入了解 C# 之后,我发现除了直觉之外还有其他东西。我们都知道创建一个数组,我们可以:

int[] myInts = new int[3];
myInts[0] = 1;
myInts[1] = 2;
myInts[2] = 3;

int[] myAnotherInts = new int[] { 1, 2, 3,};  // Array Initialization Syntax

但我们不能这样做:

int[] myInts = new int[3](); // why we can't add () in the end?

虽然我们确实在集合上使用 () 作为:

List<int> myInts = new List<int>() { 1, 2, 3 };

问题 1

为什么最后不能加()?

问题 2

如果我的问题 1 的答案是 Array 是一个抽象类:

public abstract class Array : ICloneable, IList, ICollection, IEnumerable...

但是也使用了'new'关键字,表示调用了构造函数,表示创建了一个实例,这不违反抽象类规则不允许创建实例吗?

【问题讨论】:

标签: c# arrays .net


【解决方案1】:

为什么最后不能加()?

你希望它能做什么?基于 C 的语言渴望简洁;您可以通过介绍您引用的数组初始化语法看到,c# 开发团队有兴趣提供使代码更紧凑、更简单同时仍然可读的方法。考虑 LINQ 与循环、字符串插值、增强“is”以提供实例、速记属性、async/await 机制、null 传播器和 ??运算符.. 我们过去写得更完整的东西的所有可避免的速记

数组维度声明后的空括号不会添加任何有用、可读、简化的内容,也不会做任何实际操作,它们只会增加声明数组时按下的键数。然而,在普通构造函数的上下文中,它们确实添加了一些有用的东西——它们告诉编译器和你的同伴“我打算调用无参数构造函数”。在创建数组(例如,从 Array 派生的 int[])时,您不会选择这种构造函数,因此为它提供工具是没有意义的。您还需要记住,维度数组通常什么都没有。您可以创建一个包含一百万个字符串的数组,但只调用了一个构造函数;制作数组的那个..数组槽为空,等你说array[x] = new String(...)

如果你的目标是提供括号或括号值意味着我们不仅可以声明一个数组,还可以使用一个新对象初始化数组中的每个元素,该对象的构造函数使用传递的括号参数调用,那么当然,它是一个选项你可以把它推荐给语言团队;我觉得它不会获得太大的吸引力,因为一个充满相同对象的数组可能充其量只是一个狭窄的用例,并且可以通过子类化和为你的类声明一个自定义默认值来解决

还使用了'new'关键字,表示调用了构造函数,表示创建了一个实例,这不违反抽象类规则不允许创建实例吗?

我想我明白你在说什么,但你必须明白 Array 是所有数组的基类,你不会自己直接实例化它,因此不会破坏抽象规则。您创建一个 int[] 并在内部编译器/系统进行必要的改组以使其从 Array 派生;通常建议您继续使用提供的语言结构来创建诸如 ibt[] 之类的东西,它们具体派生自抽象数组。如果一个构造函数被调用,你就看不到它,或者给它提供参数,所以真的不需要你写括号——任何东西

要记住的一点是,编译器会在将您编写的代码编译成 IL 之前进行大量的重写。上面列出的大多数简写都会被编译器默默地扩展为长手变体,有时会相当复杂,所以如果你正在阅读一些东西并认为“这看起来不像 c# 1.0”,只需知道它或 babky 看起来很多当编译器完成预处理时,它更像是 c# 的原始最长手形式

【讨论】:

  • 所以当您提到派生自 Array 的 int[] 时,您能告诉我派生类型 int[] 的类型吗?我想在 VS 的 Go to definition (F12) 中查看它是如何从 Array 基类派生而来的
猜你喜欢
  • 2014-08-23
  • 2010-10-13
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多