为什么这段代码无效
int K = 3;
double[,] a = new double[K,K];
它以错误退出" 字段初始化程序无法引用非静态字段"
编辑:我在一个类中编写了这段代码。我很好奇,如果它在一个类或一个方法中,它会有什么不同。答案 0 :(得分:4)
看起来a
是一个对象的字段。要使K
静态:
static int K = 3;
double[,] a = new double[K, K];
或者在构造函数中初始化a
。
要回答您更新的问题:
当声明为字段时,您无法引用非静态成员,因为您无法控制字段初始化的顺序(除非您按照我的建议使用构造函数)。因此编译器不能说在K
初始化之前已为a
分配了一个值。
在方法中声明时,K
已初始化,因为它是第一个。
答案 1 :(得分:1)
那么,你期待什么?
想让数组大小保持静态,但不必在任何地方重复这些维度吗?使用常量。
const int ArraySize = 3;
double[,] a = new double[ArraySize, ArraySize];
希望大小取决于外部的参数吗?使用参数化构造函数:
double[,] a;
public YourClass(int arraySize)
{
a = new double[arraySize, arraySize];
}
想要将数组及其大小作为实际变量吗?不要将其定义为字段! :)
public void YourMethod()
{
var arraySize = 3;
var array = new double[arraySize, arraySize];
}
请注意,在C#中(与Pascal不同),数组的大小不是定义的一部分。因此,您不必在实际需要创建数组实例之前指定它,然后您可以稍后将更大的数组分配给相同的引用,例如。
我认为没有合理的理由让大小成为一个字段,特别是如果它不是静态的。即使是静态的,它也是糟糕的设计。所以想想你实际上要做的事情有点困难 - 如果在C#中很难做到,你可能会错过一些简单的问题解决方案,或者你试图在C#中编写不同的语言:) / p>
你不能按照你的方式编写它的基本原因,但是可以在方法中使用它很简单 - 方法是一个有序的指令列表。虽然这只是一种简化,但您可以将其视为保证以特定顺序发生的事情。因此,您首先将3
分配给K
,然后使用K
的值创建新数组。到目前为止,非常好。
另一方面,字段不保证以任何给定的顺序初始化。它不再是一个有序的指令列表,运行时(和编译器)可以自由地做任何它认为最好的事情。通过将初始化移动到显式构造函数,您再次强制执行固定的顺序;突然,K = 3
将再次发生在new double[K, K]
之前。