如何在变量声明 (CS0270) 中强制执行数组的长度?

Posted

技术标签:

【中文标题】如何在变量声明 (CS0270) 中强制执行数组的长度?【英文标题】:How do I enforce the length of an array in variable declaration (CS0270)? 【发布时间】:2019-01-06 04:39:25 【问题描述】:

为什么 C# 的设计不允许这样的声明?

public int[10] someInts;
public int[10] someMethod();

这些行会引发 CS0270 错误。这背后的原因是什么?在接口中强制数组长度或重写类的能力在某些情况下会很有用。

编辑:

根据 Marc Gravell 的评论,我想指出的事实是,数组的长度在创建时与其类型一样已知。如果我们在将数组分配给字段/返回值时可以强制执行数组的类型,为什么我们不能强制执行它的长度?它会使这样的代码失败:

int length = 10;
int[] arr = new int[length];
int[10] anotherArr = arr; //length not known at compile time

和这个一样:

string obj1 = "";
object obj2 = "";
obj1 = obj2; //cannot implicitly convert type 'object' to 'string'

【问题讨论】:

why we can't enforce its length 因为编译器不这样做 - 没有人内置该功能。blogs.msdn.microsoft.com/ericgu/2004/01/12/minus-100-points 显示了您在添加“简单功能”时需要考虑的那种想法(和这绝对是不是一个简单的功能)。 【参考方案1】:

数组的长度在您创建时确定;您没有在那里创建任何数组,因此您无法确定长度。您不能在字段签名或方法签名的返回部分中定义数组的长度。

该字段仅包含对数组的引用:它的长度取决于任何代码创建数组并将其分配给该字段 该方法只返回一个数组:它的长度取决于任何代码创建数组并返回它

声明中唯一的长度是“固定缓冲区”,但是:那不是数组(它有点像数组,但是:不是数组;它也是一个大多数人永远不需要使用的高级主题。

【讨论】:

感谢您的回答,但真的不可能使这些声明成为不可能吗?数组的长度在创建时就像它的类型一样是已知的(两者都是固定的),所以为什么我们不能在从方法分配/返回它时检查它(当然它会使得不可能分配任何具有编译时长度未知到这样的字段,即使长度是正确的)? @anuar2k 创建时知道 if 这是一个微不足道的场景。大多数不是。但是,您可以执行一些操作,例如将数组包装在一个类中,该类通过索引器公开值并始终分配一个固定大小的数组。或者,您可以使用结构化和“固定缓冲区”来做同样的事情【参考方案2】:

虽然 C# 没有此功能,但 C#(和其他 .NET 语言)编译成的中间代码 - 通用中间语言(CIL,也称为 IL 或 MSIL) - 确实允许您将数组的维度指定为类型的一部分。来自the relevant ECMA spec,第 I.8.9.1 节:

通过指定数组的元素类型、数组的秩(维数)以及数组每个维的上下限来定义数组类型。 [...] 虽然每个维度的实际边界仅在运行时才知道,但签名可以指定在编译时已知的信息(例如,无边界、下限 界,或上下界)。

在 CIL 中,您可以声明符合 C# 定义的数组,其下限为 0,上限未指定,例如int32[]。您还可以指定一个明确的上限,例如int32[0...5].

您可以使用与 CIL 配合使用的工具 - 例如 the ILSupport Visual Studio extension - 将具有明确上限的数组定义为字段、参数等。但我不能说其他用 C# 编写的代码有多好使用它。

【讨论】:

以上是关于如何在变量声明 (CS0270) 中强制执行数组的长度?的主要内容,如果未能解决你的问题,请参考以下文章

C++:如何强制派生类设置基成员变量?

如何强制 PyCharm 警告未声明的类型?

Unity:列表变量数组。如何在 C# 中正确声明它

C#里error CS0136: 无法在此范围中声明名为“e”的局部变量或参数

unity脚本中变量在另一个脚本如何调用

如何在javascript中声明php数组变量并查看数据表