如何在变量声明 (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) 中强制执行数组的长度?的主要内容,如果未能解决你的问题,请参考以下文章