Если ваш проект CLI (Common Language Runtime Support), то:
Вы можете использовать класс массива, а не тот, который вы получаете при написании:
#include <array>
using namespace std;
Другими словами, не неуправляемый класс массива, который вы получаете при использовании пространства имен std и при включении заголовка массива, а не неуправляемого класса массива, определенного в пространстве имен std и в заголовке массива, а в массиве управляемого класса CLI.
с этим классом, вы можете создать массив любого ранга, который вы хотите.
Следующий код ниже создает новый двухмерный массив из 2 строк и 3 столбца и типа int, и я называю it "arr":
array<int, 2>^ arr = gcnew array<int, 2>(2, 3);
Теперь вы можете получить доступ к элементам в массиве, по имени и написать только квадратные скобки []
, а внутри них добавить строку и столбец и отделить их с запятой ,
.
Следующий код ниже относится к элементу во второй строке и первом столбце массива, который я уже создал в предыдущем коде выше:
arr[0, 1]
только для записи эта строка должна прочитать значение в этой ячейке, т. е. получить значение в этой ячейке, но если вы добавите знак =
, вы собираетесь записать значение в этой ячейке, то есть установить значение в этой ячейке. Вы также можете использовать операторы + =, - =, * = и / =, только для чисел (int, float, double, __int16, __int32, __int64 и т. Д.), Но вы уже знаете это.
Если ваш проект не CLI, вы можете использовать неуправляемый класс массива пространства имен std, если вы #include <array>
, конечно, но проблема в том, что этот класс массива отличается от массива CLI. Создать массив такого типа аналогичен CLI, за исключением того, что вам придется удалить знак ^
и gcnew
. Но, к сожалению, второй параметр int в скобках <>
указывает длину (т. Е. Размер) массива, а не его ранг!
Невозможно указать ранг в этом типе массива, ранг - это CLI массив.
std array ведет себя как обычный массив в c ++, который вы определяете с помощью указателя, например int*
, а затем: new int[size]
или без указателя: int arr[size]
, но в отличие от Обычный массив c ++, std array предоставляет функции, которые вы можете использовать с элементами массива, такие как fill, begin, end, size и т. д., но обычный массив ничего не предоставляет.
Но все же std-массив являются одномерными массивами, такими как обычные c ++-массивы. Но благодаря решениям, которые другие ребята предлагают о том, как вы можете превратить обычный двумерный массив c ++ в двумерный массив, мы можем адаптировать те же идеи к std-массиву, например. в соответствии с идеей Мехрдада Афшари, мы можем написать следующий код:
array<array<int, 3>, 2> array2d = array<array<int, 3>, 2>();
Эта строка кода создает «жуткий массив», который является одномерным массивом, который каждая из его ячеек является или указывает на другой одномерный массив.
Если все одномерные массивы в одномерном массиве равны по длине / размеру, то вы можете рассматривать переменную array2d как реальный двумерный массив, плюс вы можете использовать специальные методы для обрабатывать строки или столбцы, зависит от того, как вы это рассматриваете, в 2D-массиве, который поддерживает std-массив.
Вы также можете использовать решение Кевина Лони:
int *ary = new int[sizeX*sizeY];
// ary[i][j] is then rewritten as
ary[i*sizeY+j]
, но если вы используете std-массив, код должен выглядеть по-другому:
array<int, sizeX*sizeY> ary = array<int, sizeX*sizeY>();
ary.at(i*sizeY+j);
И все еще имеют уникальные функции массива std.
Обратите внимание, что вы по-прежнему можете получить доступ к элементам std с помощью []
круглых скобок, и вам не нужно вызывать функцию at
. Вы также можете определить и присвоить новую переменную int, которая будет вычислять и сохранять общее количество элементов в std-массиве и использовать его значение вместо повторения sizeX*sizeY
. Вы можете определить свой собственный двухмерный массив generic class и определить конструктор класса двумерных массивов для получения двух целых чисел, чтобы указать количество строк и столбцов в новом двухмерном массиве и определить функцию get, которая получает два параметра целого числа, которые обращаются к элементу в двумерном массив и возвращает его значение, и задайте функцию, которая получает три параметра, две первые являются целыми числами, которые определяют строку и столбец в двумерном массиве, а третий параметр - новое значение элемента. Его тип зависит от типа, который вы выбрали в родовом классе.
Вы сможете реализовать все это, используя либо обычный массив c ++ (указатели или без), либо массив std и используйте одну из идей что другие люди предложили и упростили использование, как массив cli, или как двухмерный массив, который вы можете определить, назначить и использовать в C #.
Первый выдаст исключение, если исходный тип не может быть брошен к целевому типу. Последний приведет к sc2, являющемуся нулевой ссылкой, но никаким исключением.
[Редактирование]
Мой исходный ответ является, конечно, самым явным различием, но поскольку Eric Lippert указывает , это не единственное. Другие различия включают:
И наконец, с помощью 'в качестве' по сравнению с оператором броска, Вы также говорите, что "я не уверен, успешно выполнится ли это".
Также обратите внимание, что можно только использовать в качестве ключевого слова со ссылочным типом или nullable типом
т.е.:
double d = 5.34;
int i = d as int;
не скомпилирует
double d = 5.34;
int i = (int)d;
, скомпилирует.
Преобразование типа использования, "как", конечно, намного быстрее, когда состав исполнителей перестал работать, поскольку это избегает расхода выдачи исключения.
, Но это не быстрее, когда бросок успешно выполняется. График в http://www.codeproject.com/KB/cs/csharpcasts.aspx вводит в заблуждение, потому что он не объясняет, что он измеряет.
нижняя строка:
, Если бы Вы ожидаете, что бросок успешно выполнится (т.е. отказ было бы исключительным), используйте бросок.
, Если Вы не знаете, успешно выполнится ли это, используйте "в качестве" оператора и протестируйте результат на пустой указатель.
Различие между двумя подходами - то, что первое ((SomeClass)obj) может заставить конвертер типов быть названным.
Вот хороший способ помнить процесс, что каждый из них следует за этим, я использую при попытке решить, который лучше для моего обстоятельства.
DateTime i = (DateTime)value;
// is like doing
DateTime i = value is DateTime ? value as DateTime : throw new Exception(...);
и следующее должно быть легко предположить то, что это делает
DateTime i = value as DateTime;
в первом случае, если значение не может быть брошено, чем исключение выдается во втором случае, если значение не может быть брошено, я устанавливаюсь в NULL.
, Таким образом, в первом случае твердая остановка сделана, если сбои броска во втором броске, которым сделана мягкая остановка и Вы могли бы встретиться с NullReferenceException позже.
Чтобы подробно остановиться комментарий Rytmis, Вы не можете использовать в качестве ключевое слово для структур (Типы Значения), поскольку у них нет нулевого значения.
Все это относится к ссылочным типам, типы значения не могут использовать as
ключевое слово, поскольку они не могут быть пустыми.
//if I know that SomeObject is an instance of SomeClass
SomeClass sc = (SomeClass) someObject;
//if SomeObject *might* be SomeClass
SomeClass sc2 = someObject as SomeClass;
синтаксис броска более быстр, но только, когда успешный, это намного медленнее для сбоя.
Лучшая практика должна использовать as
, когда Вы не знаете тип:
//we need to know what someObject is
SomeClass sc;
SomeOtherClass soc;
//use as to find the right type
if( ( sc = someObject as SomeClass ) != null )
{
//do something with sc
}
else if ( ( soc = someObject as SomeOtherClass ) != null )
{
//do something with soc
}
Однако, если Вы абсолютно уверены, что someObject
экземпляр SomeClass
тогда бросок использования.
В.Net 2 или выше дженериков означают, что у Вас очень редко должен быть невведенный экземпляр класса ссылки, таким образом, последний менее часто используется.
Вводный бросок выдает исключение, если попытка броска перестала работать. "Поскольку" состав исполнителей возвращает пустой указатель, если попытка броска перестала работать.
Они выдадут различные исключения.
(): NullReferenceException
как: InvalidCastException
, Который мог помочь для отладки.
, "поскольку" ключевое слово пытается бросить объект и если состав исполнителей перестал работать, пустой указатель возвращается тихо. () оператор броска сразу выдаст исключение, если состав исполнителей перестанет работать.
"Только используют C# "в качестве" ключевого слова, где Вы ожидаете, что бросок перестанет работать в неисключительном случае. Если бы Вы рассчитываете на бросок для следования и не подготовлены для получения какого-либо объекта, который перестал бы работать, необходимо использовать () оператор броска так, чтобы соответствующее и полезное исключение было выдано".
Для примеров кода и дальнейшего объяснения: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html
Для тех из Вас с опытом VB.NET, (тип) совпадает с DirectCast и, "как тип" совпадает с TryCast.
Это похоже на различие между Синтаксическим анализом и TryParse. Вы используете TryParse, когда Вы ожидаете, что он мог бы перестать работать, но когда у Вас будет сильное обеспечение, он не приведет Вас к сбою Синтаксический анализ использования.