なぜC#は長い変数をオブジェクト変数に変換してからulongに暗黙的に変換できないのですか?
long a = 0;
Object c = a;
ulong b = (ulong)c; // throw exception here
なぜC#は長い変数をオブジェクト変数に変換してからulongに暗黙的に変換できないのですか?
long a = 0;
Object c = a;
ulong b = (ulong)c; // throw exception here
箱に入れられたのとまったく同じタイプにのみ箱を開けることができます
Object c = a
長い箱a
ulong b = (ulong)c;
cをulongとして開梱しようとしますが、長いため失敗します。
ulong b = (ulong)((long)c);
cを長い間箱から出してしまうので、うまくいくでしょう。c長いと、これは機能し、longからulongにキャストできます。
値型Tをボックス化する場合、ボックス化を解除できるのは、それ自体またはNullable(T?)としてのみです。その他のキャストは無効です。
これは、オブジェクトからのキャストが変換として解釈されることは決してないのに対し、はlongとulongの間の変換であるためです。
したがって、これは合法です。
var c = (long) b;
これも合法です:
var c = (long?) b;
しかし、これはそうではありません:
var c = (ulong) b;
やりたいことを行うには、2回キャストする必要があります。1回目は開梱のみで、2回目は実際の変換です。
var c = (ulong)(long) b;
詳細については、EricLippertによるこのブログ投稿を参照してください。
long
上記のすべての値がaの最大値(9,223,372,036,854,775,807)より大きい場合、データが失われます。
ulong
最小値はゼロ、最大値は18,446,744,073,709,551,615です。
このリスクなしで変換するには、
ulong b = Convert.ToUInt64(c);
短くて簡単な答え:longとulongは同じタイプではないためです。1つは符号付きロングで、もう1つは符号なしロングです。