Кастинг: (NewType) против объекта как NewType
Возможный дубликат:
Кастинг vs с использованием ключевого слова 'as' в среде CLR
В чем разница между этими двумя приведениями?
SomeClass sc = (SomeClass)SomeObject;
SomeClass sc2 = SomeObject as SomeClass;
Обычно они должны быть явными приведениями к указанному типу?
Ответы
Ответ 1
Первый будет генерировать исключение, если тип источника не может быть передан целевому типу. Последнее приведет к тому, что sc2 будет пустой ссылкой, но не будет исключением.
[изменить]
Мой оригинальный ответ, безусловно, является самым выраженным различием, но, как указывает Эрик Липперт это не единственный. Другие отличия:
- Вы не можете использовать оператор "как" для приведения к типу, который не принимает "null" в качестве значения
- Вы не можете использовать 'as' для преобразования вещей, например чисел в другое представление (например, float to int).
И, наконец, используя "как" против оператора трансляции, вы также говорите "Я не уверен, что это удастся".
Ответ 2
Также обратите внимание, что вы можете использовать только ключевое слово as с ссылочным типом или типом с нулевым значением
т
double d = 5.34;
int i = d as int;
не будет компилироваться
double d = 5.34;
int i = (int)d;
будет компилироваться.
Ответ 3
Typecasting с использованием "as", конечно, намного быстрее, когда сбой выполняется, поскольку он позволяет избежать затрат на выброс исключения.
Но это не так быстро, когда литье преуспевает. Граф http://www.codeproject.com/KB/cs/csharpcasts.aspx вводит в заблуждение, потому что он не объясняет, что он измеряет.
В нижней строке:
-
Если вы ожидаете, что прилив будет успешным (т.е. отказ будет исключительным), используйте листинг.
-
Если вы не знаете, будет ли это удастся, используйте оператор "as" и проверьте результат для null.
Ответ 4
Разница между двумя подходами заключается в том, что первый ((SomeClass) obj) может вызывать преобразование типа .
Ответ 5
Вот хороший способ запомнить процесс, который каждый из них следует из того, что я использую, пытаясь решить, что лучше для моих обстоятельств.
DateTime i = (DateTime)value;
// is like doing
DateTime i = value is DateTime ? value as DateTime : throw new Exception(...);
а следующее должно быть легко угадать, что он делает
DateTime i = value as DateTime;
в первом случае, если значение не может быть отлито, чем исключение генерируется во втором случае, если значение не может быть выбрано, я устанавливается в нуль.
Итак, в первом случае жесткая остановка выполняется, если при выполнении броска во втором нажатии выполняется мягкая остановка, и позже вы можете столкнуться с NullReferenceException.
Ответ 6
Хорошо Оператор "как" "помогает" вам похоронить проблему ниже, потому что, когда ему предоставляется несовместимый экземпляр, он возвращает null, возможно, вы передадите это методу, который пройдет это к другому и так далее, и, наконец, вы получите исключение NullReferenceException, которое затруднит вашу отладку.
Не злоупотребляйте им. Оператор прямого трансляции лучше в 99% случаев.
Ответ 7
Чтобы развернуть комментарий Rytmis, вы не можете использовать ключевое слово as для structs (Типы значений), так как они не имеют нулевого значения.
Ответ 8
Все это относится к ссылочным типам, типы значений не могут использовать ключевое слово 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
, используйте функцию cast.
В .Net 2 или выше дженерики означают, что вам очень редко нужно иметь не типизированный экземпляр ссылочного класса, поэтому последний используется менее часто.
Ответ 9
В скобках бросается исключение, если попытка броска не выполняется. "As" cast возвращает null, если попытка броска завершается с ошибкой.
Ответ 10
Они будут бросать разные исключения.
(): NullReferenceException
as: InvalidCastException
Это может помочь для отладки.
Ключевое слово "as" пытается передать объект, и если приведение происходит неудачно, null возвращается молча. Оператор cast() будет выдавать исключение немедленно, если сбой выполняется.
"Используйте только ключевое слово С#" как ", в котором вы ожидаете, что бросок завершится неудачей в случае, не относящемся к исключительным случаям. Если вы рассчитываете, что бросок будет успешным и не готовы к получению какого-либо объекта, который потерпит неудачу, вы должны использовать(), чтобы исключить соответствующее и полезное исключение.
Для примеров кода и дополнительного объяснения: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html
Ответ 11
Это похоже на разницу между Parse и TryParse. Вы используете TryParse, когда ожидаете, что он может потерпеть неудачу, но когда у вас есть сильная уверенность, это не подведет вас к использованию Parse.
Ответ 12
Для тех из вас, кто имеет опыт работы с VB.NET, (тип) совпадает с DirectCast, а "как тип" совпадает с TryCast.
Ответ 13
И ради полноты, У Эрика Липперта есть сообщение в блоге о различии и некоторых оговорках.