Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# CLR如何知道装箱对象的类型?_C#_Clr_Type Conversion_Boxing - Fatal编程技术网

C# CLR如何知道装箱对象的类型?

C# CLR如何知道装箱对象的类型?,c#,clr,type-conversion,boxing,C#,Clr,Type Conversion,Boxing,当值类型被装箱时,它被放置在一个非类型化的引用对象中。 那么,是什么导致了这里的无效强制转换异常呢 long l = 1; object obj = (object)l; double d = (double)obj; 不,它不是放在非类型化的对象中。对于每个值类型,CLR中都有一个装箱引用类型。所以你会有这样的想法: 这种装箱类型在C#中无法直接访问,尽管它在C++/CLI中。显然,它知道原始类型。因此,在C#中,变量必须具有编译时类型object,但这并不意味着这就是对象的实际类型 有关更

当值类型被装箱时,它被放置在一个非类型化的引用对象中。 那么,是什么导致了这里的无效强制转换异常呢

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

不,它不是放在非类型化的对象中。对于每个值类型,CLR中都有一个装箱引用类型。所以你会有这样的想法:

这种装箱类型在C#中无法直接访问,尽管它在C++/CLI中。显然,它知道原始类型。因此,在C#中,变量必须具有编译时类型
object
,但这并不意味着这就是对象的实际类型


有关更多详细信息,请参见or。

Jon Skeet的回答涵盖了原因;至于如何绕过它,以下是您必须做的:

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

双重铸造的原因是:;当.NET取消对变量的装箱时,它只知道如何将它取消装箱到装箱时所使用的类型(
long
,在您的示例中)。一旦您取消了装箱,并且有了一个合适的
long
原语,您就可以将它强制转换为
double
或任何其他类型的可从
long
强制转换的类型。我在这里回答您的问题:


很有趣,谢谢你,乔恩。瓦格纳的有效C#声明:“装箱将值类型放置在非类型化的引用对象中”。我很确定这也说明了装箱对象不包含任何类型元数据,尽管我现在找不到那个特殊的引用。正是在读那本书的时候,我想到了这个问题。@Fearofahackplanet:我不想对Bill说他到底是什么意思,但box对象肯定知道它的原始类型,包括枚举。(输入一个枚举值,然后直接使用ToString,而不用拆箱来证明:)我相信这是一个很好的演示<代码>长l=40L;对象o=(对象)l;WriteLine(o.GetType())在这种情况下,System.Int64将打印到屏幕上。尽管
o
是一个对象,但底层类型仍然是一个很长的类。
long l = 1;
object obj = (object)l;
double d = (double)(long)obj;