最初に: これについての私の理解は、CType(b, Int16) は (Int16)b と同じではないということです。1 つは型の変換 (CType) で、もう 1 つはキャストです。(Int16)b は、CType(b, Int16) ではなく、DirectCast(b, Int16) と同等です。
(MSDN に記載されているように) 2 つの違いは、有効な変換がある限り CType が成功することですが、DirectCast ではオブジェクトの実行時の型が同じであることが必要です。設計時に、このオブジェクトがその型に変換するように指示するのではなく、その型であることをコンパイラに伝えています。
参照: http://msdn.microsoft.com/en-us/library/7k6y2h6x(VS.71).aspx
ただし、根本的な問題は、32ビット整数を16ビット整数に変換しようとしているということです...[必要な単語がありません。おそらく誰かがここに挿入してください]損失があります。16 ビットから 32 ビットへの変換はロスレスであるため許可されますが、32 ビットから 16 ビットへの変換は未定義です。C# で機能する理由については、@Roman の回答を参照してください。これは、C# がオーバーフローをチェックしないという事実に関連しています。
UInt16.MaxValueの結果の値&H7FFFFFFF And &HFFFF
(65535) UInt16 は 0 から 65535 まで実行されます。-32768 から 32767 まで実行される Int16 にそれを詰め込もうとしていますが、ご覧のとおり動作しません。また、この値が UInt16 に収まる可能性があるという事実は偶然であり、2 つの 32 ビット整数を追加して 16 ビット整数 (ショート) に詰め込もうとすると、オーバーフローが頻繁に発生するため、これは本質的に危険な操作であると言えます。