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());
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
}