我在这里尝试做的事情应该通过下面的代码来显而易见
public class RangeInfo
{
public int[2] Range { set; }
public string Text { set; }
}
public readonly RangeInfo[4] Ranges = new RangeInfo[4] {
new RangeInfo { Range = new int[2] {Int32.MinValue,70}, Text = "..." },
new RangeInfo { Range = new int[2] {70,80}, Text = "..." },
new RangeInfo { Range = new int[2] {80,90}, Text = "..."},
new RangeInfo { Range = new int[2] {90,Int32.MaxValue}, Text = "..." }
};
但是我遇到了很多错误,比如
无法在变量声明中指定数组大小
on public int[2]
,
预期,类,代表,枚举或结构
on RangeInfo[4]
我做错了什么?
答案 0 :(得分:7)
Length是数组实例的属性,不是类型的一部分。数组变量仅包含指向数组的指针。因此,字段,属性和其他变量声明与长度无关。您只能在实例化数组时指定长度,而不能在声明变量时指定长度。
如果您需要数组具有特定长度,则属性设置器可以在运行时检查长度,如果长度错误则抛出异常。但是,在编译时无法强制执行此操作。
更易于维护的解决方案可能是根本不使用数组,而是为数组中当前表示的每个值创建一个具有单独属性的类。这假设特定指数的值具有不同的含义。如果数组真的只代表一组值,那么你最好使用List。见https://en.wikipedia.org/wiki/Zero_one_infinity_rule
答案 1 :(得分:5)
数组长度不是类型签名的一部分,因此长度为2的数组的类型与长度为3的数组的类型相同。唯一的类型是int[]
,表示任意长度的int数组
如果你来自C ++,这可能会让人感到困惑,因为数组可能是"在行中" 或参考。在C#数组中,就像其他引用类型一样(除非明确告知为stackalloc)堆已分配,因此您的变量只是指向堆上数组的指针。
如果你想限制大小,你需要在属性的setter中约束它(或者最好 - 在你的类的构造函数中,从那时起你可以使类不可变)。
public class RangeInfo
{
public RangeInfo(IList<int> range, string txt)
{
if (range == null || range.Count != 2)
throw new ArgumentException(..);
Range = range.ToArray();
Info = txt;
}
public int[] Range { get; private set; }
public string Info { get; private set; }
}
然而,对于这种类型的构造,我宁愿只将两个int传递给ctor,并且有两个int字段(这样你就不必堆堆分配一个数组)。你也可以使用元组或声明一个int对类。您仍然可以通过返回new[]{a,b}
将这两个内部int字段公开为数组。
顺便说一句:固定大小的数组确实存在于C#中,但主要用于互操作。为了调用一些需要64个连续32位整数的C API,声明这样的结构将是非常愚蠢的:
struct FooStruct
{
int int0;
int int1;
..
int int63;
}
因此,可以创建一个仅仅模仿上述内容的fixed int[64]
。
[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct FooStruct
{
fixed int[64] data;
}
答案 2 :(得分:1)
我将您的代码更改为编译,但保持接近您最初尝试实现的目标。
public class RangeInfo
{
private string _text;
private int[] _range;
public int[] Range
{
set
{
if (value.Length != 2)
throw new Exception("Length must be 2.");
if (_range == null)
_range = new int[2];
_range[0] = value[0];
_range[1] = value[1];
}
get
{
return _range;
}
}
public string Text { set { _text = value; } get { return _text; } }
}
static public readonly RangeInfo[] Ranges = new RangeInfo[4] {
new RangeInfo { Range = new int[] {Int32.MinValue,70}, Text = "..." },
new RangeInfo { Range = new int[] {70,80}, Text = "..." },
new RangeInfo { Range = new int[] {80,90}, Text = "..."},
new RangeInfo { Range = new int[] {90,Int32.MaxValue}, Text = "..." }
};