В чем собственно разница между этими двумя слепками?
SomeClass sc = (SomeClass)SomeObject;
SomeClass sc2 = SomeObject as SomeClass;
Обычно, разве они оба не должны быть явным приведением к указанному типу?
В чем собственно разница между этими двумя слепками?
SomeClass sc = (SomeClass)SomeObject;
SomeClass sc2 = SomeObject as SomeClass;
Обычно, разве они оба не должны быть явным приведением к указанному типу?
Первый вызовет исключение, если исходный тип не может быть приведен к целевому типу. Последнее приведет к тому, что sc2 будет пустой ссылкой, но не будет исключением.
[Редактировать]
Мой первоначальный ответ, безусловно, является наиболее заметной разницей, но, как сказал Эрик Липперт указывает, что это не единственный вариант. Другие отличия включают:
И, наконец, используя «as» вместо оператора приведения, вы также говорите: «Я не уверен, что это удастся».
Также обратите внимание, что вы можете использовать ключевое слово as только со ссылочным типом или типом, допускающим значение NULL.
ie:
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 вводит в заблуждение, потому что не объясняет, что он измеряет.
Итог:
Если вы ожидаете, что приведение будет успешным (т. Е. Отказ будет исключительным), используйте приведение.
Если вы не знаете, удастся ли это сделать, используйте оператор «as» и проверьте результат на нуль.
Разница между этими двумя подходами заключается в том, что первый объект ((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;
в первом случае, если значение не может быть приведено, возникает исключение, во втором случае, если значение не может быть приведено, i устанавливается в значение null.
Таким образом, в первом случае выполняется жесткая остановка, если приведение не удается во втором приведении, выполняется мягкая остановка, и в дальнейшем вы можете столкнуться с исключением NullReferenceException.
Что ж, оператор "as" "помогает" избавиться от проблемы на более низком уровне, потому что, когда ему предоставляется несовместимый экземпляр, он вернет значение null, возможно, вы передадите его методу, который передаст его другому и так далее, и, наконец, вы получите исключение NullReferenceException, которое затруднит отладку.
Не злоупотребляйте этим. Оператор прямого приведения лучше в 99% случаев.
Чтобы развернуть комментарий Ритмиса, вы не можете использовать как ключевое слово для структур (типов значений), поскольку они не имеют нулевого значения.
Все это относится к ссылочным типам, типы значений не могут использовать ключевое слово 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 или выше универсальные шаблоны означают, что вам очень редко нужно иметь нетипизированный экземпляр ссылочного класса, поэтому последний используется реже.
Приведение в скобках вызывает исключение, если попытка приведения не удалась. Приведение "as" возвращает null, если попытка приведения не удалась.
Это похоже на разницу между Parse и TryParse. Вы используете TryParse, когда ожидаете, что он может потерпеть неудачу, но когда у вас есть надежная уверенность, что он не подведет, вы используете Parse.
Для тех из вас, у кого есть опыт работы с VB.NET, (тип) такой же, как DirectCast, а «as type» - это то же самое, что и TryCast.
Они выбрасывают разные исключения.
(): NullReferenceException
как: InvalidCastException
Что может помочь при отладке.
Ключевое слово as пытается преобразовать объект, и если преобразование завершается неудачно, возвращается null. Оператор приведения () немедленно вызовет исключение в случае сбоя приведения.
Используйте ключевое слово C # as только в том случае, если вы ожидаете, что приведение не удастся в неисключительном случае. Если вы рассчитываете на успешное приведение типов и не готовы к получению какого-либо объекта, который выйдет из строя, вам следует использовать оператор приведения (), чтобы возникло соответствующее и полезное исключение.
Примеры кода и дополнительные пояснения: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html