Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.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# 不应该';这不管用吗?(打字/拆箱)_C# - Fatal编程技术网

C# 不应该';这不管用吗?(打字/拆箱)

C# 不应该';这不管用吗?(打字/拆箱),c#,C#,但这不是我的问题:)。我正在做一件运行时的事情,这超出了本文的范围。因为源代码是IList,所以我不知道其中的类型。我原以为编译器可以在不首先将对象解包为int的情况下强制转换对象???不,它不能。拆箱不是铸造。您需要取消绑定变量,然后强制转换它。在这种特殊情况下,这意味着两次强制转换 当您强制转换为double时,运行时(不是编译器!)不知道如何将对象强制转换为double,也不尝试取消装箱,因为没有任何说明您需要这样做。事实上,您希望对对象进行强制转换,而不是对已装箱的变量进行强制转换是完全

但这不是我的问题:)。我正在做一件运行时的事情,这超出了本文的范围。因为源代码是IList,所以我不知道其中的类型。我原以为编译器可以在不首先将对象解包为int的情况下强制转换对象???

不,它不能。拆箱不是铸造。您需要取消绑定变量,然后强制转换它。在这种特殊情况下,这意味着两次强制转换

当您强制转换为
double
时,运行时(不是编译器!)不知道如何将
对象强制转换为
double
,也不尝试取消装箱,因为没有任何说明您需要这样做。事实上,您希望对
对象
进行强制转换,而不是对已装箱的变量进行强制转换是完全合理的。代码的意图是不明确的,设计者可能已经决定将其全部抛出

最后一行的双重强制转换引发异常

没错。装箱的T只能解装箱到T或T

我原以为编译器可以在不首先将对象解包为int的情况下强制转换该对象

好的,您正在构建一个运行时,所以它将为您构建一个角色来解决这个问题仔细描述您期望编译器发出的代码,记住编译器当然不知道其中有int


非常有用的提示:如果装箱对象的类型是动态的而不是对象,则转换为double成功。也就是说,
(double)(dynamic)(g[0])
可以按照您的预期工作。“动态”只是一个戴着滑稽帽子的“对象”,那么为什么一个失败,另一个成功呢?

这是一个似是而非的猜测,但并不完全正确。这里的歧义不是真正的问题。是的,当我说“可能已经决定”时,我是在猜测:)看看你和SledgeHammer是否能找出限制取消装箱必须取消装箱到实际类型的实际原因。(或者可以为空)好的,所以动态强制转换确实可以工作,但是它生成的IL对于我的需要来说有点太乱了。现在我使用“emit call _miItem”来获取项目,该部分工作正常。是否有一种方法可以“模拟”dynamic的功能。也就是说,在我调用_miItem之后,对它调用GetType(),然后将miItem的结果作为GetType()的结果取消装箱?看起来像是操作码。UnboxAny需要一个“硬编码”类型?@SledgeHammer:你发现为你想要的东西生成的代码很糟糕,你的问题是“有更好的方法吗?”如果我知道更好的方法,你不认为我们会生成代码吗?@SledgeHammer:现在,在这里,你可以做一些狭隘的事情,专注于你要加倍努力的事实。例如,您可以使用
Convert.ToDouble
方法
dynamic
不会这样做,因为
dynamic
必须做C编译器会做的事情,而
ToDouble
不会做C编译器会做的事情。()你的第二个回答是我的问题。。。dynamic需要做很多我不知道的事情。。。我的最终目的是,将IList和foreach放到我创建的目标数组中。我知道的源代码是IList,目标代码是X类型(在本例中是double,但也可以是long,等等。例如……任何有意义的东西)。因此,我创建的数组是X类型的,但在这种情况下取消装箱不起作用,因为类型不匹配。。。我有点想做Convert.ChangeType所做的,减去巨大的性能损失。嗯。。也许调用Convert.ChangeType()会起作用。。。对其进行了基准测试,(双)(int)转换为4ms,而ChangeType()转换为48ms,迭代次数为1M。。。所以有一点点的成功。。。除非我找到更好的方法。。。但至少,我可以在特殊情况下使用emit代码,仅当源代码是IList时才执行此路径。
public IList A23 { get; set; }

s.A23 = new List<int>(new int[] { 62, 63, 64 });

IList g = s.A23;
double d = (double)g[0];
double d = (double)(int)g[0];