2010-08-19 3 views
11

Я нахожу это поведение TryCast в .NET 4.0/VS 2010 довольно запутанным.TryCast не работает, когда работает DirectCast (.NET 4.0)

В моем понимании 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?

ответ

16

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

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

EDIT

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

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

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

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

+0

Я только что подтвердил, что вы предложили. DirectCast() действительно генерирует исключение при запуске в реальной оценке. Спасибо за разъяснения! – motto

+0

Было бы очень аккуратно, если бы вы могли точно объяснить, что произошло. – SLaks

+0

@SLaks, добавлено быстрое объяснение. – JaredPar

Смежные вопросы