Возможный дубликат:. Кастинг против использования ключевого слова 'as' в CLR
В чем, собственно, разница между этими двумя кастами?
SomeClass sc = (SomeClass)SomeObject;
SomeClass sc2 = SomeObject as SomeClass;
Как правило, они оба должны быть явными приведениями к указанному типу?
В первом случае возникнет исключение, если исходный тип не может быть приведен к целевому типу. Во втором случае sc2 будет нулевой ссылкой, но исключения не будет.
[Редактировать]
Мой первоначальный ответ, конечно, является наиболее выраженным различием, но, как указывает Eric Lippert указывает, оно не единственное. Другие различия включают:
И наконец, используя 'as' против оператора cast, вы'также говорите "Я'не уверен, что это получится"
Также обратите внимание, что Вы можете только использовать в качестве ключевого слова со справочным типом или nullable типом
т.е.:
double d = 5.34;
int i = d as int;
не соберет
double d = 5.34;
int i = (int)d;
соберет.
Приглашение на однотипные роли использующий " as" конечно, намного быстрее, когда состав исполнителей терпит неудачу, поскольку он избегает расхода броска исключения.
Но это не быстрее, когда бросок добивается успеха. Граф в http://www.codeproject.com/KB/cs/csharpcasts.aspx вводит в заблуждение потому что это doesn' t объясняют что it' s измерение.
Итог:
Если бы Вы ожидаете, что бросок добьется успеха (т.е. неудача была бы исключительной), используйте бросок.
Если Вы don' t знают, будет ли это иметь успех, используйте " as" оператор и тест результат для пустого указателя.
Различие между двумя подходами - то, что первое ((SomeClass)obj) может заставить [конвертер типа] [1] быть названным.
[1]: http://msdn.microsoft.com/en-us/library/yy580hbd (Против 80) .aspx
Хорошо ' as' оператор " helps" Вы хороните свою проблему путь ниже , потому что, когда этому предоставляют несовместимый случай, это возвратит пустой указатель, возможно, you' проход ll, что к методу, который передаст его другому и так далее и наконец you' ll получают NullReferenceException, который сделает Вашу отладку тяжелее.
Don' t злоупотребляют им. Прямой оператор броска лучше в 99% случаев.
Вот хороший способ помнить процесс, что каждый из них следует за этим, я использую, пытаясь решить, который лучше для моего обстоятельства.
DateTime i = (DateTime)value;
// is like doing
DateTime i = value is DateTime ? value as DateTime : throw new Exception(...);
и следующее должно быть легко предположить то, что это делает
DateTime i = value as DateTime;
в первом случае, если стоимость не может быть брошена, чем исключение брошено во второй случай, если стоимость не может быть брошена, я собираюсь аннулировать.
Таким образом, в первом случае твердая остановка сделана, если состав исполнителей терпит неудачу во втором броске, мягкая остановка сделана, и Вы могли бы столкнуться с NullReferenceException позже.
Подробно остановиться на Rytmis' s комментарий, Вы can' t используют в качестве ключевое слово для структур (Типы Стоимости), поскольку у них нет нулевого значения.
Все это относится к справочным типам, типы стоимости не могут использовать 'в качестве' ключевого слова, поскольку они не могут быть пустыми.
//if I know that SomeObject is an instance of SomeClass
SomeClass sc = (SomeClass) someObject;
//if SomeObject *might* be SomeClass
SomeClass sc2 = someObject as SomeClass;
Синтаксис броска более быстр, но только, когда успешный, it' s намного медленнее, чтобы потерпеть неудачу.
Лучшая практика должна использовать 'в качестве' когда Вы don' t знают тип:
//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
Что может помочь при отладке.
Ключевое слово "as" пытается привести объект, и если приведение не удается, то null возвращается молча. Оператор приведения () немедленно выбросит исключение, если приведение не удалось.
"Используйте ключевое слово C# "as" только в тех случаях, когда вы ожидаете, что приведение не удастся в исключительном случае. Если вы рассчитываете на успех приведения и не готовы получить какой-либо объект, который потерпит неудачу, вам следует использовать оператор () cast, чтобы было выброшено соответствующее и полезное исключение."
Примеры кода и дальнейшее объяснение: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html
Приведение с круглыми скобками выбрасывает исключение, если попытка приведения не удалась. Приведение "as" возвращает null, если попытка приведения не удалась.