Почему ошибка "Указанный приведение недействительна" * не * раскрывает основную причину?

Просто наткнулся на простую ошибку, и это вызывает интересный вопрос. Окружающая среда: VS 2010, NET.4, С#. Получение возвращаемого значения из SQL sproc привело к тому, что исключение "Указанный приведение недействительно":

cm.Parameters.Add( "@si", SqlDbType.SmallInt ).Direction=   ParameterDirection.ReturnValue;
..
cm.ExecuteNonQuery( );
short   siRetVal=   (short) cm.Parameters[0].Value;     // exception here

Поскольку код работал в режиме отладки и был прерван в этой строке, я набрал окно Immediate:

?(short) cm.Parameters[0].Value

и результат:

Cannot unbox 'cm.Parameters[0].Value' as a 'short'

Хорошо, SQL sproc возвращает 32-разрядный int (а не 16-разрядный short, как я думал изначально), что объясняет исключение. Должна использовать правильную ширину для этого параметра - никаких вопросов об этом.

Но может ли кто-нибудь объяснить , почему основная причина ошибки сообщается только в окне Immediate Window? В Except Helper не было обнаружено никаких подробностей, внутреннее исключение было пустым. Разве не было бы полезно узнать точную причину? Я думаю, что анализ ошибок намного проще, не?


Изменить: добавлен скриншот; трассировка стека не кажется намеком на любой код ADO.NET(чего я не ожидал). Более того, если я оставлю параметр ret-value "объявление" как SmallInt, но предоставит переменную правильной ширины (или, как показано на рисунке), разместив int, все будет работать! Я совершенно уверен, что нет никакого отношения к ADO/SQL.

Я считаю, что @HansPassant раскрывает истинную природу происходящего здесь, и я склонен принять это как ответ. Хотя неудобно обнаружить, что управляемый код не может даже предоставить мне точные сведения о состоянии выполнения (например, какая ссылка на самом деле является нулевой - как упоминалось, или в этом случае с недопустимым литом).

Ответы

Ответ 1

Если вы профилируете SQL, сгенерированный ADO.NET, вы можете обнаружить, что ADO.NET попытался явно ввести ваш выходной параметр как smallint. Поэтому, когда SQL Server выполнил ваш запрос, он попытался присвоить значение, возвращаемое хранимой процедурой (int), в переменную, которую вы сказали ей создать как tinyint. Я считаю, что исключение исключений вы видите от SQL Server, а не от .NET.

В командном окне вы используете CLR, а не механизм запросов TSQL. Возможно, ваша проблема может быть связана с механизмом запросов, а не с .NET.