Кастинг: (NewType) по сравнению с объектом как NewType [дубликат]

Если ваш проект 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 #.

85
задан Community 23 May 2017 в 12:25
поделиться

11 ответов

Первый выдаст исключение, если исходный тип не может быть брошен к целевому типу. Последний приведет к sc2, являющемуся нулевой ссылкой, но никаким исключением.

[Редактирование]

Мой исходный ответ является, конечно, самым явным различием, но поскольку Eric Lippert указывает , это не единственное. Другие различия включают:

  • Вы не можете использовать 'в качестве' оператора для кастинга к типу, который не принимает 'пустой указатель' как значение
  • , Вы не можете использовать относительно , преобразовывают вещи, как числа к различному представлению (плавание к интервалу, например).

И наконец, с помощью 'в качестве' по сравнению с оператором броска, Вы также говорите, что "я не уверен, успешно выполнится ли это".

86
ответ дан Rytmis 24 November 2019 в 08:19
поделиться

Также обратите внимание, что можно только использовать в качестве ключевого слова со ссылочным типом или nullable типом

т.е.:

double d = 5.34;
int i = d as int;

не скомпилирует

double d = 5.34;
int i = (int)d;

, скомпилирует.

27
ответ дан denny 24 November 2019 в 08:19
поделиться

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

, Но это не быстрее, когда бросок успешно выполняется. График в http://www.codeproject.com/KB/cs/csharpcasts.aspx вводит в заблуждение, потому что он не объясняет, что он измеряет.

нижняя строка:

  • , Если бы Вы ожидаете, что бросок успешно выполнится (т.е. отказ было бы исключительным), используйте бросок.

  • , Если Вы не знаете, успешно выполнится ли это, используйте "в качестве" оператора и протестируйте результат на пустой указатель.

11
ответ дан Joe 24 November 2019 в 08:19
поделиться

Различие между двумя подходами - то, что первое ((SomeClass)obj) может заставить конвертер типов быть названным.

5
ответ дан Cristian Libardo 24 November 2019 в 08:19
поделиться

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

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 позже.

4
ответ дан Nick Berardi 24 November 2019 в 08:19
поделиться

Чтобы подробно остановиться комментарий Rytmis, Вы не можете использовать в качестве ключевое слово для структур (Типы Значения), поскольку у них нет нулевого значения.

3
ответ дан Community 24 November 2019 в 08:19
поделиться

Все это относится к ссылочным типам, типы значения не могут использовать 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 или выше дженериков означают, что у Вас очень редко должен быть невведенный экземпляр класса ссылки, таким образом, последний менее часто используется.

2
ответ дан Keith 24 November 2019 в 08:19
поделиться

Вводный бросок выдает исключение, если попытка броска перестала работать. "Поскольку" состав исполнителей возвращает пустой указатель, если попытка броска перестала работать.

1
ответ дан 24 November 2019 в 08:19
поделиться

Они выдадут различные исключения.
(): NullReferenceException
как: InvalidCastException
, Который мог помочь для отладки.

, "поскольку" ключевое слово пытается бросить объект и если состав исполнителей перестал работать, пустой указатель возвращается тихо. () оператор броска сразу выдаст исключение, если состав исполнителей перестанет работать.

"Только используют C# "в качестве" ключевого слова, где Вы ожидаете, что бросок перестанет работать в неисключительном случае. Если бы Вы рассчитываете на бросок для следования и не подготовлены для получения какого-либо объекта, который перестал бы работать, необходимо использовать () оператор броска так, чтобы соответствующее и полезное исключение было выдано".

Для примеров кода и дальнейшего объяснения: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

1
ответ дан Steve Willard 24 November 2019 в 08:19
поделиться

Для тех из Вас с опытом VB.NET, (тип) совпадает с DirectCast и, "как тип" совпадает с TryCast.

1
ответ дан Adam Ruth 24 November 2019 в 08:19
поделиться

Это похоже на различие между Синтаксическим анализом и TryParse. Вы используете TryParse, когда Вы ожидаете, что он мог бы перестать работать, но когда у Вас будет сильное обеспечение, он не приведет Вас к сбою Синтаксический анализ использования.

1
ответ дан ICR 24 November 2019 в 08:19
поделиться