TryCast не работает там, где работает DirectCast (.NET 4.0) - PullRequest
11 голосов
/ 19 августа 2010

Я нахожу такое поведение TryCast в .NET 4.0 / VS 2010 довольно запутанным.

В моем понимании TryCast работает как DirectCast, но ничего не выдаст, вместо выдачи исключения, если приведение невозможно.

VS 2010 / .NET 4

?TryCast(CType(1, Object), String)
Nothing
?DirectCast(CType(1, Object), String)
"1"

VS 2008 / .NET 3.5

?TryCast(CType(1, Object), String)
Nothing
?DirectCast(CType(1, Object), String)
Cannot convert to 'String'.

.NET3.5 результаты соответствуют тому, что, как я считаю, TryCast делает ... .NET 4, однако, нет.

Может кто-нибудь указать мне, в каком лучшем направлении безопасно привести объект к String в .NET 4?

1 Ответ

16 голосов
/ 19 августа 2010

На основании ваших примеров кода, начинающихся с ? Я предполагаю, что вы используете непосредственное окно для правильного выполнения теста? Проблема с этим подходом состоит в том, что непосредственное окно - интерпретация вместо фактической оценки. Это делает его восприимчивым к тонким угловым ошибкам, и это действительно один из них.

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

EDIT

Так почему же произошла регрессия? В 2010 году я полностью переписал механизм отладки VB EE (средство оценки выражений). Старая кодовая база, которую я унаследовал, была просто слишком дорогой, чтобы поддерживать ее больше. Дело в том, что добавление новых функций в движок обходилось дороже, чем переписывание его с нуля с улучшенной архитектурой, включающей новые функции.

Как уже было сказано перед отладкой вычислений, это интерпретация, а не выполнение кода. Это вызывает дублирование некоторых алгоритмов между EE и CLR / Compiler. Одной из областей, где происходит дублирование, является логика приведения. Невозможно попросить отладчик CLR привести объект времени отладки, EE несет ответственность за определение того, является ли указанный язык действительным.

У старой логики приведения EE было множество ошибок (особенно в области обобщений и массивов). Более новая инфраструктура очень близко соответствует руководящим принципам CLR. Однако у вас никогда не будет 100% -ного паритета, потому что это запретит очень полезные выражения в EE (я могу написать пост в блоге об этом в будущем). Но в большинстве случаев поведение сохраняется.

В этом конкретном случае я добавил небольшую ошибку, которая позволяет DirectCast со значением, набираемым на Object, использовать операторы преобразования времени выполнения VB по сравнению с указанным поведением, которое допускает только преобразования CLR. Следовательно, это преобразование успешно, где оно должно потерпеть неудачу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...