TryCast не работает, когда работает DirectCast (.NET 4.0)

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

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

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'.

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

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

Ответ 1

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

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

ИЗМЕНИТЬ

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

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

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

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