在string,object和int之间进行转换和解析

时间:2016-02-04 17:20:14

标签: c# .net casting

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

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

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

  1. 下拉值(字符串)下载到对象
  2. Object是一个引用类型,因此.ToString()在此实例中不执行任何操作,编译器将其省略
  3. 然后将对象解析为int:ref type =>价值类型
  4. 或者C#编译器是否会接受它,而不是在不需要时进行转换?

3 个答案:

答案 0 :(得分:4)

  

下拉值(字符串)下载到对象

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

  

object是一个引用类型,因此.ToString()在此实例中不执行任何操作,编译器将其省略

否 - 您在ToString上调用object这是一个虚方法,因此将调用object.ToString或后续覆盖(在您的情况下,为string.ToString()`。

另外,您已告诉编译器将值视为object。你希望编译器回过头来说“好吧,我知道你告诉我把它当作一个对象,但我可以从上面的代码中看出它是一个字符串,所以我会忽略它并保持它为一个字符串“。编译器不会那么努力。 JIT优化器可以做类似的事情,如果有铁壳保证它会起作用;否则它会做你告诉它做的事。

  

对象而不是强制转换为int

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

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

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

答案 1 :(得分:2)

不,不是真的。

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

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

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

编译器无法删除对ToString的调用,因为您已明确说过"不,此引用实际上不是字符串。它只是一个对象。",所以你必须进行虚拟方法调用。该调用将使用引用的运行时类型,因此您正在执行String.ToString(),它只返回this。但你尽力使用编译器干扰,并且编译器不会猜测你。

最后,int.Parse将解析字符串并输出一个整数。当然,这涉及通过字符串逐个字符。参考和价值类型在这里并不重要 - 它不是演员,它是一种方法调用,就像任何其他方法一样。该方法将字符串转换为数字,即“#”。一个演员只会抛出一个InvalidCastException,因为一个字符串是而不是一个整数(虽然如果你自己创建一个类型,你可以提供自己的演员方法,可以做任何你想做的事情去做)。编译器无法告诉您不能将字符串转换为整数,因为您只是说引用并不是一个字符串,而是一个object - 和一个{ {1}} 可以转换为object,如果它引用 装箱int的运行时类型。

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

int

花费你的努力来添加正确的错误处理,而不是做愚蠢的仪式:)

答案 2 :(得分:0)

1:那不正确。 "下拉值( string Up-lated object "。.NET Framework中的所有类都是派生自对象。(向基类投射向上投射。)

2:a)是对象是引用类型。

b) .ToString object 类方法(可以通过派生类覆盖)。实际上,这里发生的是 int.Parse 采用字符串参数。为此,您首先将其转换为对象,然后.ToString方法调用。

3:是的第3点是正确的