14


1

CLRはどのようにボックス化されたオブジェクトのタイプを知るのですか?

値型がボックス化されると、* untyped *参照オブジェクト内に配置されます。 ここで無効なキャスト例外の原因は何ですか?

long l = 1;
object obj = (object)l;
double d = (double)obj;

3 Answer


17


いいえ、型指定されていないオブジェクトには配置されません。 値の種類ごとに、CLRにボックス化された参照型があります。 したがって、次のような_何かがあります:

public class BoxedInt32 // Not the actual name
{
    private readonly int value;
    public BoxedInt32(int value)
    {
        this.value = value;
    }
}

そのボックス化された型は、C ++ / CLIにありますが、C#では直接アクセスできません。 明らかにそれは元の型を知っています。 そのため、C#では、変数にコンパイル時の `object`型が必要ですが、それがオブジェクトの実際の型を意味するわけではありません。

ECMA CLI仕様またはhttps://rads.stackoverflow.com/amzn/click/com/0735621632[C#経由のCLR]を参照してください。 ] 詳細については。


6


Jon Skeetの答えはその理由をカバーしています。それを回避する方法については、ここであなたがしなければならないことです:

long l = 1;
object obj = (object)l;
double d = (double)(long)obj;

デュアルキャストの理由はこれです。 .NETが変数のボックス化を解除するとき、ボックス化された型(例では long)にボックス化解除する方法を知っているだけです。それを「double」または「long」からキャスト可能な他の型に変換します。