.Net массивы с нижней границей> 0 - PullRequest
10 голосов
/ 11 сентября 2008

Хотя, возможно, это странная вещь, которую я хочу сделать, мне нужно создать массив в .Net с нижней границей> 0. Сначала это кажется возможным, используя:

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;

Что отлично работает.

Ответы [ 4 ]

3 голосов
/ 11 сентября 2008

Причина, по которой вы не можете разыгрывать одно на другое, заключается в том, что это зло.

Допустим, вы создали массив объекта [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();
    }

}
2 голосов
/ 11 сентября 2008
1 голос
/ 11 сентября 2008

Просто сохраните нижнюю границу в целочисленном смещении const и вычтите это значение из того, что ваш источник возвращает в качестве индекса.

Также: это старая функция VB6. Я думаю, что мог бы быть атрибут, чтобы помочь поддержать это.

1 голос
/ 11 сентября 2008

Я не уверен, почему это нельзя передать как Object [], но было бы нелегко, если бы вы просто создали реальный класс, чтобы обернуть массив и обработать вашу "странную логику" там?

Вы получили бы преимущества от использования реального эталонного объекта, если бы вы могли добавить «интеллект» в ваш класс.

Редактировать: Как вы используете свой массив, не могли бы вы опубликовать еще немного кода? Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...