字符串、对象和 int 之间的强制转换和分析

本文关键字:转换 之间 对象 int 字符串 | 更新日期: 2023-09-27 18:33:25

ddlSomeDropDownType.SelectedValue.aspx页面的下拉列表。我有以下代码:

int num = int.Parse(((object)this.ddlSomeDropDownType.SelectedValue).ToString());

我是否正确认为会发生以下情况:

  1. 下拉值(字符串(向下转换为对象
  2. 对象是一种引用类型,因此.ToString()在此实例中不执行任何操作,编译器会省略
  3. 然后对象被解析为 int:ref type => 值类型

或者 C# 编译器会接受这一点,而不是在不需要的时候强制转换?

字符串、对象和 int 之间的强制转换和分析

下拉值(字符串(向下转换为对象

嗯,是的,但所有的变化都是编译器如何绑定对对象的后续调用。 您告诉编译器"将此值视为object" 它不会以任何方式更改实际对象。

object 是一种引用类型,因此.ToString()在这种情况下不执行任何操作,编译器会省略

否 - 您调用ToString它是object上的虚拟方法,因此将调用object.ToString或后续覆盖(在您的情况下为字符串。ToString(('.

另外,您已经告诉编译器将该值视为object。 你希望编译器回去说"好吧,我知道你告诉我把它当作一个对象,但我可以从上面的代码中看出它是一个字符串,所以我将忽略它,只把它作为一个字符串"。 编译器不会进行该工作。 JIT 优化器可能会做类似的事情,如果有铁定的保证它会工作;否则它会按照你告诉它做的事情去做。

对象比转换为 int

否 - 它由int解析 - 与强制转换非常不同。 它将读取字符串的字符并尝试返回等效的整数值。 原始对象(字符串(保持不变,并创建一个新值(int(。 如果您"更改"原始值(在这种情况下这是不可能的,因为字符串是不可变的,但为了参数起见,让我们假设您可以(,那么解析后的整数将不会更改。 如果将对象强制转换为 int,然后更改字符串,则它们都引用相同的值,因此更改将反映在两者中。


由于SelectedValue是一个字符串,因此无需强制转换为对象然后调用ToString(),因此您的代码可以简化为

int num = int.Parse(this.ddlDiscountType.SelectedValue);

不,不是真的。

首先,您需要了解运行时类型信息和编译时类型信息之间的区别。

ddlDiscountType.SelectedValue的编译时类型为 string 。当您将其转换为 object 时,它不会更改运行时类型,只会更改编译时类型 - 实际上,您减少了引用的公共接口。

ToString 是一个虚拟方法,所以只要你不使用 new ,发生的情况取决于运行时类型,并且与编译时类型无关,只要该方法是在编译时类型中定义的。由于ToString是在Object上定义的,因此没有问题。

编译器无法删除对ToString的调用,因为您已经明确表示"不,此引用不是真正的字符串。它只是一个对象",因此您必须进行虚拟方法调用。调用将使用引用的运行时类型,因此您正在执行 String.ToString() ,它只返回 this 。但是你尽了最大的努力来干扰编译器,编译器不会事后猜测你。

最后,int.Parse将解析字符串并输出一个整数。当然,这涉及通过字符串逐个字符地进行。引用和值类型在这里并不重要 - 它不是强制转换,而是与其他任何方法调用一样的方法调用。该方法将字符串转换为数字,仅此而已。强制转换只会抛出一个InvalidCastException,因为字符串不是整数(尽管如果你创建自己的类型,你可以提供自己的强制转换方法,它可以做任何你想让他们做的事情(。编译器无法告诉您不能将字符串转换为整数,因为您刚刚说引用实际上不是字符串,而是object - 并且object可以转换为int,如果它引用的运行时类型盒装int

没有理由以如此复杂的方式做事。只需做:

var number = int.Parse(ddlDiscountType.SelectedValue);

花精力添加适当的错误处理,而不是做愚蠢的仪式:)

1:这是不正确的。"下拉值(字符串(被向上转换为对象"。.NET Framework 中的所有类都派生自 object。(向基类投射是向上投射

2: a(是,对象是引用类型。

b(.ToString对象类方法(可以被派生类覆盖(。实际上这里发生的事情是那个int。解析采用字符串参数。为此,您首先将其隐藏到对象中,然后.ToString 方法调用。

3:是的 第三点是正确的