C#装箱问题

本文关键字:装箱问题 | 更新日期: 2023-09-27 17:47:46

首先,两个例子:

// This works
int foo = 43;
long lFoo = foo;
// This doesn't
object foo = (int)43;
long? nullFoo = foo as long?; // returns null
long lFoo = (long)foo; // throws InvalidCastException
if (foo.GetType() == typeof(int))
    Console.WriteLine("But foo is an int..."); // This gets written out

现在,我猜测为什么第二个不起作用是因为拳击。此代码背后的目的是实现IComparable。我需要一些方法来将对象强制为long或ulong(如果两者都不是),而不是抛出错误。我不想对每个基本的数字类型(byte、int、long、ubyte…)进行检查,我宁愿在最大的数字类型中捕获它们并以这种方式处理。这里所有聪明人的想法?我如何打开对象的盒子,最好是避免反射,但我想如果这是唯一的方法。。。或者我应该不实现IComparable的非泛型版本吗?

编辑:

这似乎有效,但似乎是一个可怕的破解问题。只有我吗?

long lFoo = long.Parse(foo.ToString());

C#装箱问题

object foo  = (int) 43;
long   lFoo = ((IConvertible) foo).ToInt64(null);

当您转换为值类型时,实际上是在强制执行开箱IL操作,这要求您转换为的类型与装箱值完全匹配;不存在可以同时发生的隐式或显式转换。

这通常意味着,您需要使用typecode(或if/else-if-using类型)进行切换,或者,在您的情况下,先检查null,然后再检查Convert.ToInt64(),这应该会正确处理它。

不仅仅是你,然而锥虫不会引发异常。

object foo = (int)43;
long outVal;
if(long.TryParse(foo.ToString(),out outVal))
{
//take action with correct value of long
}
else
{
//maybe passed you another type of object
}