Кастинг: (NewType) против Object as NewType

В чем, собственно, разница между этими двумя кастами?

SomeClass sc = (SomeClass)SomeObject;
SomeClass sc2 = SomeObject as SomeClass;

Как правило, они оба должны быть явными приведениями к указанному типу?

Комментарии к вопросу (3)
Решение

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

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

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

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

И наконец, используя 'as' против оператора cast, вы'также говорите "Я'не уверен, что это получится"

Комментарии (0)

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

т.е.:

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

не соберет

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

соберет.

Комментарии (1)

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

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

Итог:

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

  • Если Вы don' t знают, будет ли это иметь успех, используйте " as" оператор и тест результат для пустого указателя.

Комментарии (0)

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

[1]: http://msdn.microsoft.com/en-us/library/yy580hbd (Против 80) .aspx

Комментарии (0)

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

Don' t злоупотребляют им. Прямой оператор броска лучше в 99% случаев.

Комментарии (1)

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

DateTime i = (DateTime)value;
// is like doing
DateTime i = value is DateTime ? value as DateTime : throw new Exception(...);

и следующее должно быть легко предположить то, что это делает

DateTime i = value as DateTime;

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

Таким образом, в первом случае твердая остановка сделана, если состав исполнителей терпит неудачу во втором броске, мягкая остановка сделана, и Вы могли бы столкнуться с NullReferenceException позже.

Комментарии (0)

Подробно остановиться на Rytmis' s комментарий, Вы can' t используют в качестве ключевое слово для структур (Типы Стоимости), поскольку у них нет нулевого значения.

Комментарии (0)

Все это относится к справочным типам, типы стоимости не могут использовать 'в качестве' ключевого слова, поскольку они не могут быть пустыми.

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

Комментарии (0)

It' s как различие между Разбором и TryParse. Вы используете TryParse, когда Вы ожидаете, что он мог бы потерпеть неудачу, но когда у Вас есть сильная гарантия он won' t подводят Вас Разбор использования.

Комментарии (0)

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

Комментарии (0)

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

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

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

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

Комментарии (1)

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

Комментарии (0)