То, почему делает 'как' работа ключевого слова, в то время как () бросают, не делает

//always works, returning a valid object into _page
        _page = _httpContext.Handler as System.Web.UI.Page;

//Fails throwing the exception : Unable to cast object of type 'System.Web.DefaultHttpHandler' to type 'System.Web.UI.Page'
        _page = (System.Web.UI.Page)_httpContext.Handler;

Я хотел бы знать, почему это происходит?

Править:

                //Fixes the problem
            if(_httpContext.Handler is System.Web.UI.Page)
            _page = (System.Web.UI.Page)_httpContext.Handler;

Если я отлаживаю 'как' оператор ключевого слова, я никогда не получаю нулевую ссылку (объект, всегда присваиваемый правильно). Однако () бросок создает исключения, если он не имеет если statment.

Править: После того, как приблизительно 15 пробегают класс, я смог получить пустой указатель. Кажется, что потребовалось больше выполнений для нахождения пустого указателя по сравнению с тем, как быстро () состав исполнителей поймает исключение.

СТАРЫЙ: Когда существует отладка в 'как' оператор каждый раз, когда класс выполняет хиты точки останова - никогда пустой указатель.

Когда существует отладка в' ()' оператор в, если, каждый раз точка останова совершает нападки, бросок работает правильно. Werid

7
задан Mausimo 30 April 2010 в 20:11
поделиться

9 ответов

// всегда работает, возвращая правильный объект в _page _page = _httpContext.Handler as System.Web.UI.Page;

Технически это не работает. Если вы заметите, _page будет null. Это просто не привело к ошибке.

Оператор as используется для того, чтобы сказать приложению: "Я хочу, чтобы ты попытался преобразовать это. Это может не получиться, и я это знаю, поэтому не выбрасывайте исключение. Я поступлю с ним соответствующим образом".

Преобразование () используется, чтобы сказать приложению: "Этот объект будет приведен к этому типу. Если это не так, что-то не так, и я должен знать об этом."

Разница между двумя приведениями (и когда их следует использовать) заключается в том, когда вы "думаете", что что-то можно привести к другому типу, и когда вы "знаете", что что-то можно привести к другому типу.

Вот статья Эрика Липперта на эту тему (изменена на его блог без повторной подачи): http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx

14
ответ дан 6 December 2019 в 07:05
поделиться

Отсюда:

Использование оператора as отличается от преобразования в C # тремя важными способами:

Он возвращает значение null когда переменная, которую вы пытаетесь преобразовать, не относится к запрошенному типу или не входит в цепочку наследования , вместо того, чтобы генерировать исключение . Его можно применять только к переменным ссылочного типа, конвертируемым в ссылочные типы. Использование as не будет выполнять определенные пользователем преобразования, такие как в качестве операторов неявного или явного преобразования , которые синтаксис преобразования будет выполнять . На самом деле есть две совершенно разные операции, определенные в IL , которые обрабатывают эти два ключевых слова (инструкции castclass и isinst) - это не просто "синтаксический сахар" " написан на C #, чтобы добиться этого другого поведения . Оператор as работает немного быстрее в версиях 1.0 и 1.1 из Microsoft CLR по сравнению с преобразованием (даже в тех случаях, когда нет недопустимые преобразования, которые могут серьезно снизить производительность преобразования из-за исключений).

7
ответ дан 6 December 2019 в 07:05
поделиться

Использование as ПОПЫТАЕТСЯ привести этот объект к определенному типу, но возвращает null при неудаче вместо того, чтобы выбросить исключение (тогда как приведение просто выбрасывает исключение). Уверены ли вы, что тот, в котором есть предложение as, действительно возвращает не null-объект?

0
ответ дан 6 December 2019 в 07:05
поделиться

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

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

Я склоняюсь к использованию явного приведения, когда я знаю, что приведение будет работать, но компилятор не знает, и выброс исключения будет нормальным (потому что это исключительный случай). Но если есть обоснованный шанс, что приведение будет недействительным, я предпочитаю использовать "as" и проверять на null. Это позволяет избежать вылавливания исключения, что более уродливо и затрудняет отладку, IMO.

0
ответ дан 6 December 2019 в 07:05
поделиться

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

0
ответ дан 6 December 2019 в 07:05
поделиться

Одно из основных различий между приведением as и префиксным приведением заключается в том, что префиксное приведение приведет к исключению, а приведение as просто вернет null.

4
ответ дан 6 December 2019 в 07:05
поделиться

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

На этом сайте есть хорошее описание трех различий между использованием в качестве и преобразованием:

http://en.csharp-online.net/CSharp_FAQ:_What_is_the_difference_between_using_a_cast_and_the_as_operator

0
ответ дан 6 December 2019 в 07:05
поделиться

То же самое, что и в ответе @Tejs. Неудачное преобразование с as выдает null.

Однако я буду говорить не так, как он, и в качестве общего правила вы всегда должны использовать явное приведение. Лично я предпочел бы получить исключение прямо там, где преобразование не удалось, чем на другой странице получить (казалось бы) из ниоткуда исключение в виде нулевой ссылки.

Одно из хороших применений оператора as - это преобразование данных из базы данных и нежелание проверять System.DBNull

int someint = cmd.ExecuteScalar() as int? ?? 0;
0
ответ дан 6 December 2019 в 07:05
поделиться

Если вы используете оператор «as», в случае сбоя преобразования он просто возвращает null. Если вы выполните явное приведение, оно вызовет исключение, если преобразование завершится неудачно. В этой ситуации "as" отклоняется к ожидаемому правильному типу. Явное преобразование не может перейти к желаемому типу.

Как правило, вы всегда должны использовать «как», если вам действительно не нужно явное приведение (например, когда вам нужно преобразовать в типы значений).

0
ответ дан 6 December 2019 в 07:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: