Convert.ToInt32和(int)有什么区别?

bal*_*hmi 52 c# type-conversion

以下代码抛出编译时错误,如

无法将'string'类型转换为'int'

string name = Session["name1"].ToString();
int i = (int)name;
Run Code Online (Sandbox Code Playgroud)

而下面的代码编译成功并执行:

string name = Session["name1"].ToString();
int i = Convert.ToInt32(name);
Run Code Online (Sandbox Code Playgroud)

我想知道:

  1. 为什么第一个代码会产生编译时错误?

  2. 2个代码片段之间的区别是什么?

Nol*_*rin 66

(int)foo只是对Int32(int在C#中)类型的强制转换.这是建立在CLR和要求foo是数字变量(例如float,long等),在这个意义上,它是非常类似于C的投

Convert.ToInt32被设计为一般转换功能.它比铸造做得更好; 也就是说,它可以从任何原始类型转换为int(最值得注意的是,解析a string).您可以在MSDN上看到此方法的完整重载列表.

正如Stefan Steiger 在评论中提到的那样:

另外,请注意,在数字级别上,(int) footruncates foo(ifoo = Math.Floor(foo)),同时Convert.ToInt32(foo)使用half甚至舍入(将x.5 舍入到最接近的EVEN整数,意思是ifoo = Math.Round(foo)).因此,结果不仅仅是实现方式,而且在数值上也不一样.

  • 另请注意,在数值级别上,(int)foo截断foo(ifoo = floor(foo)),而ToInt32(foo)使用数学舍入(=将x.5舍入到最接近的偶数整数,意味着ifoo = Math.Round (FOO)).因此,结果不仅仅是实现方式,而且在数值上也不一样. (19认同)

Mar*_*ell 18

(这一行涉及一个被合并的问题)你永远不应该使用(int)someString- 这将永远不会工作(并且编译器不会让你).

然而,int int.Parse(string)bool int.TryParse(string, out int)(及其各种重载)是公平的游戏.

就个人而言,我主要Convert在我处理反射时使用,所以对我来说,选择是ParseTryParse.第一种是当我希望该值是一个有效的整数时,并希望它抛出异常.第二个是当我想检查它是否是一个有效的整数时 - 我可以决定当它是/不是时该做什么.


eco*_*fey 5

引用Eric Lippert的文章:

Cast意味着两个相互矛盾的事情:"检查这个对象是否真的属于这种类型,如果不是则抛出"和"此对象不属于给定类型;找到属于给定类型的等效值".

所以你在1.)中试图做的是声明是一个String是一个Int.但由于String不是int,因此该断言失败.

2.)成功的原因是因为Convert.ToInt32()解析字符串并返回一个int.它仍然可能失败,例如:

Convert.ToInt32("Hello");
Run Code Online (Sandbox Code Playgroud)

会导致Argument异常.

总而言之,从String转换为Int是一个框架问题,而不是.Net类型系统中隐含的东西.