2

我有一个object大于零的数字(授予)。让我们给它 42。它最初是HttpContext.Session集合的一部分。

Session["myNumber"] = 42;
object obj = Session["myNumber"];

我尝试将它用作带有强制转换的int:

int num = (int)obj;

这返回0

但是,我设法得到了我想要做的事情:

int num = int.Parse(obj.ToString());

这给了我42.

这有意义吗,可能是声明或类型有问题吗?

4

4 回答 4

5

我在下面要说明的关键点是,是的,如果实际obj不是真正的int但足够int像 unbox 工作的东西,那么它可能是可能的。就理解它而言,我在这里要看的主要内容是:什么是obj.GetType().

好的,邪恶的代码: - 首先是重要的一点:

static void Main()
{
    object obj = Evil();
    int i = (int)obj; // 0
    int j = int.Parse(obj.ToString()); // 42
}

我是怎么做到这个怪物的?

我撒谎和欺骗......基本上,我是这样做的:

enum bar {
    @42 = 0 // not legal C#... "42" is not a valid identifier
}

但在 CLI 级别它是有效的......

static object Evil()
{
    var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(
        new AssemblyName("foo"), AssemblyBuilderAccess.Run);
    var mb = ab.DefineDynamicModule("foo");
    var eb = mb.DefineEnum("bar", TypeAttributes.Public, typeof(int));
    eb.DefineLiteral("42", 0);
    Type t = eb.CreateType();
    return Enum.ToObject(t, 0);
}
于 2012-10-18T09:07:53.153 回答
3

你所描述的根本不会发生。

如果您0在拆箱对象时获得值,则该对象实际上包含一个 boxed int,并且它实际上具有 value 0

拆箱值的唯一方法是使用该值的确切类型,这意味着如果它不是int.

您的代码中必须有其他原因导致此问题。

于 2012-10-18T09:09:57.330 回答
1

是的,它确实有意义,因为“42”可以用多种方式表示。它是一个字符串吗?是整数吗?它是一个十六进制字符串吗?是香蕉和橙子吗(不是开玩笑)?

因此,当您询问 C#“int.Parse”时,您告诉 C#“这个东西是一个使用标准 C# 字符串表示法表示整数的整数。

当你用“(int)obj”行告诉 C# 时,你是在说这个东西已经是一个整数,就像你喜欢的那样。

希望有帮助。

于 2012-10-18T09:01:43.807 回答
1

当我执行代码时

        object obj = 42;

        int num = (int)obj; 

        int num2 = int.Parse(obj.ToString()); 

在这两种情况下它都返回 42。

所以,你的 obj 必须是 object 以外的东西(如你所说)。所以我们需要声明的类型 og obj 来进一步回答这个问题。

于 2012-10-18T09:03:38.097 回答