В чем разница между T [,] и T [*, *]?
Мой Google-джитсу меня не сбит. Вопрос в заголовке... В чем разница между T[,]
и T[*,*]
?
Я ищу ответ на 2, 2-1/2:
-
Простой английский (или супер-архитектор) объяснение с примером кода.
-
Ссылка на официальную документацию этого различия.
Бонус: укажите в подразделе и номер страницы в спецификации С# 4, которая определяет это. (Это не в секте 12 "Массивы" )
Я получил это понятие здесь.
Ответы
Ответ 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]()
Надеюсь, вам понравится.