Сведения о вопросе

nikolya

16:03, 1st July, 2020

Теги

c#   .net    

Приведение: (NewType) против объекта как NewType

Просмотров: 369   Ответов: 12

Возможный Дубликат:
Приведение против использования ключевого слова 'as' в CLR

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

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

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



  Сведения об ответе

pumpa

18:03, 1st July, 2020

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

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

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

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

И наконец, используя 'as' против оператора cast, вы также говорите "I'm not sure if this will succeed."


  Сведения об ответе

nYU

18:03, 1st July, 2020

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

т.е.:

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

не будет компилироваться

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

будет компилировать.


  Сведения об ответе

PROGA

18:03, 1st July, 2020

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

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

Суть в следующем:

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

  • Если вы не знаете, получится ли это, Используйте оператор "as" и проверьте результат для null.


  Сведения об ответе

SKY

18:03, 1st July, 2020

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


  Сведения об ответе

DO__IT

18:03, 1st July, 2020

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

Не злоупотребляйте им. Оператор прямого приведения лучше в 99% случаях.


  Сведения об ответе

#hash

18:03, 1st July, 2020

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

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


  Сведения об ответе

DAAA

18:03, 1st July, 2020

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


  Сведения об ответе

прога

18:03, 1st July, 2020

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

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


  Сведения об ответе

screen

18:03, 1st July, 2020

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


  Сведения об ответе

$DOLLAR

18:03, 1st July, 2020

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

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

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

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


  Сведения об ответе

SKY

18:03, 1st July, 2020

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


  Сведения об ответе

+-*/

18:03, 1st July, 2020

Для тех из вас, кто имеет опыт VB.NET, (тип) - это то же самое, что и DirectCast, а "as type"-это то же самое, что и TryCast.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться