简体   繁体   English

C#拳击问题

[英]C# boxing question

First, two examples: 首先,两个例子:

// 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

Now, my guess as to why the second doesn't work is because of boxing. 现在,我猜测为什么第二个不起作用是因为拳击。 The purpose behind this code is to implement IComparable . 此代码背后的目的是实现IComparable I need some way to coerce an object into either a long or a ulong as appropriate, or if it's neither, than to throw an error. 我需要一些方法来强制将对象强制转换为long或ulong,或者如果不是,则抛出错误。 I don't want to have to implement checks for each basic numeric type (byte, int, long, ubyte, ...) I'd rather just catch them in the largest numeric type and deal with it that way. 我不想为每个基本的数字类型(byte,int,long,ubyte,...)实现检查。我宁愿用最大的数字类型捕获它们并以这种方式处理它。 Thoughts from all the smart people here? 这里所有聪明人的想法? How can I unbox the object, preferably avoiding reflection, but I suppose if that's the only way... Or should I just not implement the non-generics version of IComparable ? 我怎样才能拆开对象,最好避免反射,但我想如果这是唯一的方法......或者我应该不实现IComparable的非泛型版本?

Edit: 编辑:

This seems to work, but seems like a horrible hack around the problem. 这似乎有效,但似乎是一个可怕的黑客围绕这个问题。 Is it just me? 只有我吗?

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

When you're casting to a value type you're really forcing an unbox IL operation, which requires that the type you're casting to matches exactly the boxed value; 当你转换为值类型时,你真的强制执行unbox IL操作,这需要你所投射的类型与盒装值完全匹配; there are no conversions, implicit, or explicit that can happen at the same time. 没有可以同时发生的转换,隐式或显式转换。

This usually means that you either need to do a switch using the typecode (or an if/else if using types), or, in your case, go with a check for null followed by Convert.ToInt64(), which should deal with it correctly. 这通常意味着您需要使用类型代码进行切换(或者使用if / else,如果使用类型),或者,在您的情况下,请检查null,然后使用Convert.ToInt64(),它应该处理它正确。

Its not just you, however tryparse does not raise an exception. 它不仅仅是你,不过tryparse不会引发异常。

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM