ddlSomeDropDownType.SelectedValue
是.aspx
页面的下拉列表。
我有以下代码:
int num = int.Parse(((object)this.ddlSomeDropDownType.SelectedValue).ToString());
我认为发生以下情况是正确的:
.ToString()
在此实例中不执行任何操作,编译器将其省略或者C#编译器是否会接受它,而不是在不需要时进行转换?
答案 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点是正确的