C# 拳击问题

发布于 2024-07-06 10:23:52 字数 754 浏览 5 评论 0原文

首先,两个例子:

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

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. 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. 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. 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?

Edit:

This seems to work, but seems like a horrible hack around the problem. Is it just me?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

等待我真够勒 2024-07-13 10:23:52
object foo  = (int) 43;
long   lFoo = ((IConvertible) foo).ToInt64(null);
object foo  = (int) 43;
long   lFoo = ((IConvertible) foo).ToInt64(null);
岁月如刀 2024-07-13 10:23:52

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

这通常意味着您需要使用类型代码(或者如果使用类型则使用 if/else)进行切换,或者在您的情况下,检查 null 后跟 Convert.ToInt64(),这应该处理它正确。

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; 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.

香草可樂 2024-07-13 10:23:52

不仅仅是你,但是 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
}

Its not just you, however tryparse does not raise an exception.

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文