Question

Although perhaps a bizare thing to want to do, I need to create an Array in .Net with a lower bound > 0. This at first seems to be possible, using:

Array.CreateInstance(typeof(Object), new int[] {2}, new int[] {9});

Produces the desired results (an array of objects with a lower bound set to 9). However the created array instance can no longer be passed to other methods expecting Object[] giving me an error saying that:

System.Object[*] can not be cast into a System.Object[]. What is this difference in array types and how can I overcome this?

Edit: test code =

Object x = Array.CreateInstance(typeof(Object), new int[] {2}, new int[] {9});
Object[] y = (Object[])x;

Which fails with: "Unable to cast object of type 'System.Object[*]' to type 'System.Object[]'."

I would also like to note that this approach DOES work when using multiple dimensions:

Object x = Array.CreateInstance(typeof(Object), new int[] {2,2}, new int[] {9,9});
Object[,] y = (Object[,])x;

Which works fine.

OTHER TIPS

The reason why you can't cast from one to the other is that this is evil.

Lets say you create an array of object[5..9] and you pass it to a function F as an object[].

How would the function knows that this is a 5..9 ? F is expecting a general array but it's getting a constrained one. You could say it's possible for it to know, but this is still unexpected and people don't want to make all sort of boundary checks everytime they want to use a simple array.

An array is the simplest structure in programming, making it too complicated makes it unsusable. You probably need another structure.

What you chould do is a class that is a constrained collection that mimics the behaviour you want. That way, all users of that class will know what to expect.

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();
    }

}

I'm not sure about why that can't be passed as Object[], but wouldn't be easy if you just create a real class to wrap an array and handle your "weird logic" in there?

You'd get the benefits of using a real reference object were you could add "intelligence" to your class.

Edit: How are you casting your Array, could you post some more code? Thanks.

Just store your lower bound in a const offset integer, and subtract that value from whatever your source returns as the index.

Also: this is an old VB6 feature. I think there might be an attribute to help support it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top