虽然想要做的事情可能很奇怪,但我需要在.Net中创建一个带有下限>的数组。这最初似乎是可能的,使用:
Array.CreateInstance(typeof(Object), new int[] {2}, new int[] {9});
生成所需的结果(下限设置为9的对象数组)。但是,创建的数组实例不能再传递给期望Object[]
给出错误的其他方法:
System.Object[*]
无法投放到System.Object[]
。数组类型有什么不同,我该如何克服这个?
编辑:测试代码=
Object x = Array.CreateInstance(typeof(Object), new int[] {2}, new int[] {9});
Object[] y = (Object[])x;
失败的原因是:“无法将'System.Object [*]'类型的对象强制转换为'System.Object []'。”
我还想指出,这种方法 DOES 在使用多个维度时有效:
Object x = Array.CreateInstance(typeof(Object), new int[] {2,2}, new int[] {9,9});
Object[,] y = (Object[,])x;
哪种方法正常。
答案 0 :(得分:3)
你不能从一个人转向另一个人的原因是这是邪恶的。
假设您创建了一个对象数组[5..9],并将其作为对象[]传递给函数F.
该函数如何知道这是5..9? F期待一个普通阵列,但它正在受到约束。你可以说它有可能知道,但这仍然是意料之外的,人们不希望每次想要使用一个简单的数组时都进行各种边界检查。
数组是编程中最简单的结构,使其过于复杂,使其无法使用。你可能需要另一种结构。
你要做的是一个类,它是一个模仿你想要的行为的约束集合。这样,该类的所有用户都知道会发生什么。
class ConstrainedArray<T> : IEnumerable<T> where T : new()
{
public ConstrainedArray(int min, int max)
{
array = new T[max - min];
}
public T this [int index]
{
get { return array[index - Min]; }
set { array[index - Min] = value; }
}
public int Min {get; private set;}
public int Max {get; private set;}
T[] array;
public IEnumerator<T> GetEnumerator()
{
return array.GetEnumarator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return array.GetEnumarator();
}
}
答案 1 :(得分:2)
答案 2 :(得分:1)
我不确定为什么不能将它作为Object []传递,但如果你只是创建一个真正的类来包装一个数组并处理你那里的“怪异逻辑”,那就不容易了?
如果您可以为您的班级添加“智力”,您将获得使用真实参考对象的好处。
编辑:你如何投射你的数组,你可以发布更多的代码吗?感谢。
答案 3 :(得分:1)
只需将下限存储在const偏移量整数中,然后从源返回的任何值中减去该值作为索引。
另外:这是一个旧的VB6功能。我认为可能有一个属性来帮助支持它。
答案 4 :(得分:0)
知道这是一个老问题,但要完全解释一下。
如果键入代码无法创建类型(在这种情况下为下界> 0的一维数组),则键入代码无法使用简单反映的类型实例。
您已经注意到的内容已经在文档中
请注意,从运行时的角度来看,MyArray []!= MyArray [*],但是 对于多维数组,这两个符号是等效的。那 是,Type.GetType(“ MyArray [,]”)== Type.GetType(“ MyArray [*,*]”) 计算结果为true。
在c#/ vb / ...中,您可以将反射数组保留在对象中,作为对象传递,并仅使用反射来访问其项。
-
现在您问“为什么根本没有LowerBound?”,那么COM对象不是.NET,它可以用旧的VB6编写,而实际上它具有将LowerBound设置为1的数组对象(或者任何VB6具有这样的自由度)还是诅咒,取决于您问的是谁。要访问此类对象的第一个元素,您实际上需要使用“ comObject(1)”而不是“ comObject(0)”。因此,检查下限的原因是在执行此类对象的枚举时要知道从何处开始枚举,因为COM对象中的元素函数期望第一个元素为LowerBound值,而不是零(0),所以支持该值是合理的在这种情况下,逻辑相同。想象您的第一个元素的get元素值为0,并使用一些Com对象将索引值为1或什至索引值为2001的元素实例传递给方法,代码会非常混乱。
简单地说:它主要仅用于旧版支持!