Convert.ToInt32 和 (int) 有啥区别?

Posted

技术标签:

【中文标题】Convert.ToInt32 和 (int) 有啥区别?【英文标题】:What is the difference between Convert.ToInt32 and (int)?Convert.ToInt32 和 (int) 有什么区别? 【发布时间】:2010-12-09 04:34:53 【问题描述】:

以下代码会引发类似的编译时错误

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

string name = Session["name1"].ToString();
int i = (int)name;

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

string name = Session["name1"].ToString();
int i = Convert.ToInt32(name);

我想知道:

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

    2个代码sn-ps有什么区别?

【问题讨论】:

有趣。通常问题是Convert.ToInt32() 和(Int32.ParseInt32.TryParse())之间有什么区别:-) 第一个是显式强制转换,您是说 name 是一个 int,从那时起应该这样引用。第二个接受字符串并转换为 int,从而有效地解析它。 @DanielDawes 这有点误导 - C# 中的有效转换确实发生了转换。例如,存储在浮点数中的位与存储在转换为 int 的值中的位完全不同。 【参考方案1】:

(int)foo 只是转换为Int32(C# 中的int)类型。这是 CLR 中内置的,要求 foo 是数字变量(例如 floatlong 等)。从这个意义上说,它与 C 中的强制转换非常相似。

Convert.ToInt32 被设计成一个通用的转换函数。它比铸造更重要。也就是说,它可以从 any 原始类型转换为int(最值得注意的是,解析string)。您可以查看此方法 here on MSDN 的完整重载列表。

正如Stefan Steiger 提到的in a comment:

另外,请注意,在数字级别上,(int) foo 会截断fooifoo = Math.Floor(foo)),而Convert.ToInt32(foo) 使用half to even rounding(将x.5 舍入到最接近的偶数整数,即ifoo = Math.Round(foo))。因此,结果不仅在实现方面,而且在数值上相同。

【讨论】:

另外,请注意,在数字级别上, (int) foo 会截断 foo (ifoo = floor(foo)),而 ToInt32(foo) 使用数学舍入(=将 x.5 舍入到最接近的 EVEN整数,意思是 ifoo = Math.Round(foo))。因此,结果不仅在实现方面,而且在数字上也不相同。 请在您的答案中包含@StefanSteiger 关于四舍五入的说明。这可以挽救生命(: 还有兴趣:(int)UInt32.MaxValue 为 -1,而 Convert.ToInt32(UInt32.MaxValue) 抛出 OverflowException。【参考方案2】:

(此行与已合并的问题有关)您永远不应该使用(int)someString - 这永远不会起作用(而且编译器不会让您这样做)。

但是,int int.Parse(string)bool int.TryParse(string, out int)(以及它们的各种重载)是公平的游戏。

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

【讨论】:

第三段第一句一读自相矛盾;应该是“主要仅在以下情况下使用Convert”......还是我只是不明白? @DaxFohl,他想说的是,如果他在项目中使用Convert,几乎可以肯定它与反射结合使用。我将其解释为,作为一个更通用的接口,当您不知道是否需要将某些值转换为 intdouble、其他原始类型或某些用户类型时,它很有用,直到运行时.例如,Convert.ChangeType() 对此很有用。【参考方案3】:

引用此Eric Lippert article:

Cast 意味着两个矛盾的东西:“检查这个对象是否真的是这个类型,如果不是就抛出”和“这个对象不是给定类型;给我找一个属于给定类型的等价值”。

所以你在 1.) 中试图做的是断言是的,一个字符串是一个 Int。但该断言失败,因为 String 不是 int。

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

Convert.ToInt32("Hello");

会导致 Argument 异常。

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

【讨论】:

【参考方案4】:

不能通过显式转换将字符串转换为 int。必须使用int.Parse 进行转换。

Convert.ToInt32 基本上包装了这个方法:

public static int ToInt32(string value)

    if (value == null)
    
        return 0;
    
    return int.Parse(value, CultureInfo.CurrentCulture);

【讨论】:

【参考方案5】:

您说的是 C# 转换操作与 .NET 转换实用程序

C# 语言级 casting 使用括号 - 例如(int) - 并且对它的转换支持是有限的,依赖于类型之间的隐式兼容性,或者开发人员通过conversion operators 明确定义的指令。 .NET Framework 中存在许多转换方法,例如System.Convert,允许在相同或不同的数据类型之间转换

(Casting) 语法适用于数值数据类型,也适用于“兼容”数据类型。兼容是指通过继承(即基类/派生类)或通过实现(即接口)建立关系的数据类型。

转换也可以在定义了conversion operators 的不同数据类型之间起作用。

另一方面,System.Convert 类是一般意义上转换事物的许多可用机制之一;它包含在不同的已知数据类型之间进行转换的逻辑,这些数据类型可以从一种形式逻辑更改为另一种形式。

通过允许相似数据类型之间的转换,转换甚至涵盖了与强制转换相同的部分内容。


请记住,C# 语言有自己的做事方式。 除了任何编程语言之外,底层的 .NET Framework 都有自己的处理方式。 (有时他们的意图重叠。)

将转换视为 C# 语言级别的功能,在本质上受到更多限制,通过 System.Convert 类进行转换是 .NET 框架中用于在不同类型之间转换值的众多可用机制之一。

【讨论】:

【参考方案6】:

.NET 中没有从 string 到 int 的默认转换。您可以使用 int.Parse() 或 int.TryParse() 来执行此操作。或者,正如您所做的那样,您可以使用 Convert.ToInt32()。

但是,在您的示例中,为什么要使用 ToString() 然后将其转换回 int 呢?您可以简单地将 int 存储在 Session 中并按如下方式检索它:

int i = Session["name1"];

【讨论】:

【参考方案7】:

只是一个简短的额外内容:在不同的情况下(例如,如果您将 double、&c 转换为 Int32),在这两者之间进行选择时,您可能还需要担心舍入。 Convert.Int32 将使用银行家的四舍五入(MSDN); (int) 只会截断为整数。

【讨论】:

【参考方案8】:

1) C# 是类型安全语言,不允许您将字符串分配给数字

2) 第二种情况将字符串解析为新变量。 在您的情况下,如果 Session 是 ASP.NET 会话,那么您不必在此处存储字符串并在检索时将其转换回来

int iVal = 5;
Session[Name1] = 5;
int iVal1 = (int)Session[Name1];

【讨论】:

【参考方案9】:

这已经讨论过了,但我想分享一个 dotnetfiddle。

如果你正在处理算术运算并使用float、decimal、double等,你最好使用Convert.ToInt32()。

using System;

public class Program

  public static void Main()
  
    double cost = 49.501;
    Console.WriteLine(Convert.ToInt32(cost));
    Console.WriteLine((int)cost);
  

输出

50
49

https://dotnetfiddle.net/m3ddDQ

【讨论】:

【参考方案10】:

Convert.ToInt32

return int.Parse(value, CultureInfo.CurrentCulture);

但是 (int) 是类型转换,因此 (int)"2" 将不起作用,因为您不能将字符串转换为 int。但你可以像 Convert.ToInt32 那样解析它

【讨论】:

【参考方案11】:

不同之处在于第一个 sn-p 是强制转换,第二个是转换。虽然,我认为编译器错误可能会因为措辞而在这里提供更多的混乱。也许如果它说“不能将类型'string'转换为'int'会更好。

【讨论】:

【参考方案12】:

这是旧的,但另一个区别是 (int) 不会对数字进行四舍五入,以防你有一个双 ej:5.7 使用 (int) 的输出将为 5,如果你使用 Convert.ToInt()数字将四舍五入为 6。

【讨论】:

以上是关于Convert.ToInt32 和 (int) 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Convert.ToInt32()和int.Parse()区别

Convert.ToInt16 或 32 或 64 和 Int.Parse 有啥区别? [复制]

Convert.ToInt32()和int.Parse()的区别

C#中(int)int.Parse()int.TryParse()和Convert.ToInt32()的区别

更好地使用 int.Parse 或 Convert.ToInt32 [重复]

Convert.ToInt32(int)和int.Parse三者的区别