Подтвердить что ты не робот

В чем разница между T [,] и T [*, *]?

Мой Google-джитсу меня не сбит. Вопрос в заголовке... В чем разница между T[,] и T[*,*]? Я ищу ответ на 2, 2-1/2:

  • Простой английский (или супер-архитектор) объяснение с примером кода.

  • Ссылка на официальную документацию этого различия.

    Бонус: укажите в подразделе и номер страницы в спецификации С# 4, которая определяет это. (Это не в секте 12 "Массивы" )

Я получил это понятие здесь.

4b9b3361

Ответ 1

T[] означает массив с нулевым значением T (массив [0] является его первым элементом)

T[*] означает ненулевой массив T (массив [0] не является его первым элементом и может даже оказаться за пределами границ)

Ссылка из вашего вопроса объясняет, что нет массива типа T[*,*], потому что все многомерные массивы T[,] рассматриваются как массивы с неизвестной нижней границей.

Ниже приведен фрагмент кода, показывающий, как создать экземпляр T[*]. Обратите внимание, что вы не можете использовать его для T[], потому что это разные типы. a[0] здесь выкинет OutOfRangeException, индекс первого элемента в этом массиве равен 1 (ах, старые добрые дни Паскаля...).

Array a = Array.CreateInstance(typeof(String), new Int32[] { 1 }, new Int32[] { 1 });
Console.WriteLine(a.GetType());    // System.String[*]  

Дополнительный пример кода

Бонус. Спецификация языка С# говорит: "Индексы элементов массива варьируются от 0 до длины - 1". Очевидно, что язык не обеспечивает встроенную поддержку массивов, отличных от нуля, это просто настраиваемая структура данных, которую вы можете создать; хотя конкретный в том смысле, что у компилятора есть специальный символ для своего типа, и VS использует стандартный визуализатор массива для них, когда вы отлаживаете.

См. также:

Как создать 1-мерный массив в С# с индексом, начинающимся с 1

С#: ненулевые массивы не совместимы с CLS

Ответ 2

На самом деле...

С# поддерживает одномерные массивы... вроде.

Ну, это... если вы используете var.

Сначала вам нужно скомпилировать это в сборку с помощью ILAsm.exe (я знаю, это еще не С#...):

.assembly extern mscorlib
{
    .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
    .ver 2:0:0:0
}
.assembly ArrayHelper { }
.module ArrayHelper.dll
.subsystem 0x0003
.class public ArrayHelper   
{
    .method public hidebysig static !!T[...]
        CastTo1D<T>(class [mscorlib]System.Array 'array') cil managed
    {
        ldarg.0
        castclass  !!T[...]
        ret
    }
    .method public hidebysig static !!T[...] Create1D<T>(int32 len) cil managed
    {
        ldarg.0
        newobj     instance void !!T[...]::.ctor(int32)
        ret
    }
    .method public hidebysig static !!T[...]
        Create1D<T>(int32 lowerBound, int32 length) cil managed
    {
        ldarg.0
        ldarg.1
        newobj     instance void !!T[...]::.ctor(int32, int32)
        ret
    }
}

Затем вы можете сделать что-то вроде:

var my1DArray = ArrayHelper.Create<int>(1, 5);

чтобы создать 1-мерный массив длиной 5 с нижней границей 1.

Черт, даже Visual Studio поддерживает это!

Скриншот Visual Studio

Надеюсь, вам понравится.