具有下限的.Net阵列> 0

时间:2008-09-11 12:44:49

标签: .net arrays

虽然想要做的事情可能很奇怪,但我需要在.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;

哪种方法正常。

5 个答案:

答案 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的一维数组),则键入代码无法使用简单反映的类型实例。

您已经注意到的内容已经在文档中

https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/specifying-fully-qualified-type-names

  

请注意,从运行时的角度来看,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的元素实例传递给方法,代码会非常混乱。

简单地说:它主要仅用于旧版支持!