В чем разница между T [,] и T [*, *]? - PullRequest
12 голосов
/ 20 февраля 2012

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

  1. Простое английское объяснение для Layman (или супер-архитектора) с примером кода.1010 * Ссылка на официальную документацию об этом различии.

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

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

Ответы [ 2 ]

15 голосов
/ 20 февраля 2012

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[*]  

Пример кода

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

См. Также:

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

C #: ненулевоймассивы не соответствуют CLS

3 голосов
/ 20 февраля 2012

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

C # поддерживает поддержку одномерных массивов ... вроде.

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

Во-первых, вам нужно скомпилировать это в сборку, используя ILAsm.exe (я знаю, это не C # ... пока):

.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);

для создания одномерного массива длиной 5 с нижней границей 1.

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

Visual Studio Screenshot

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

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