以下代码引发的编写时间错误喜欢

不能转换的类型'string'到'int'

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

而下面的代码汇编和成功执行:

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

我想知道:

  1. 为什么第一个代码生成一个编译时间的错误?

  2. 什么之间的差2段代码?

有帮助吗?

解决方案

(int)foo 只是对 Int32 (C#中的 int )类型的强制转换。这是内置于CLR中并要求 foo 是一个数字变量(例如 float long 等)从这个意义上来说,它是非常类似于C中的演员。

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

Stefan Steiger 提及在评论中

  

另请注意,在数字级别上,(int)foo 会截断 foo ifoo = Math.Floor(foo)),而 Convert.ToInt32(foo)使用一半甚至四舍五入(将x.5舍入到最接近的偶数整数,意味着 ifoo = Math.Round(foo))。因此,结果不仅仅是实施方式,而且数字相同。

其他提示

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

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

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

引用此 Eric Lippert文章

  

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

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

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

Convert.ToInt32("Hello");

会导致Argument异常。

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

无法通过显式转换将字符串强制转换为int。必须使用 int.Parse 转换它。

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

public static int ToInt32(string value)
{
    if (value == null)
    {
        return 0;
    }
    return int.Parse(value, CultureInfo.CurrentCulture);
}

你在谈论一个C#铸造操作vs。净转化公用事业

  • C#语言级 铸造 使用括号-例如(int)-和转对它的支持是有限的,依赖于隐性的兼容性之间的类型,或明确定义的指令通过开发人员通过 转换经营者.
  • 许多转换方法存在的。净框架,例如 系统。转换, ,允许 转换 之间的相同或不同的数据类型。

(铸造) 语法工作在数字数据类型,并且还在"兼容的"数据类型。兼容的装置的数据类型,因为其中有一个关系设立的通过继承(即基地/源类)或通过执行(即接口).

铸造也可以工作之间不同的数据类型 转换经营者 定义。

系统。转换 类另一方面是一个许多可用的机制转换的东西,在一般的意识;它包含的逻辑之间的转换不同的,已知的数据类型,可以从逻辑上的改变从一种形式变成另一个。

转换,甚至涵盖了一些相同的地浇铸通过允许转换之间的类似的数据类型。


记得,C#语言都有其自己的方式做一些事情。
和底层。净框架拥有自己的做事方式,除了任何一种编程语言。
(有时,他们重叠,在他们的意图。)

想到的铸件一C#语言级别的特点,那就是更多的有限性质,和通过转换系统。把课作为一个许多可用的机制。净框架转换的价值观之间的不同种类。

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

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

int i = Session["name1"];

只是一个简短的额外:在不同的情况下(例如,如果你正在转换双倍,& c转换为Int32),你可能还想在选择这两者时担心舍入。 Convert.Int32将使用银行家的四舍五入( MSDN ); (int)将截断为整数。

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

2)第二种情况将字符串解析为新变量。  在你的情况下,如果Session是ASP.NET会话,那么你不必在那里存储字符串,并在检索

时将其转换回来
int iVal = 5;
Session[Name1] = 5;
int iVal1 = (int)Session[Name1];

Convert.ToInt32

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

但是(int)是类型转换,所以(int)" 2"因为你不能将字符串转换为int而无法工作。但是你可以像Convert.ToInt32那样解析它

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

这是旧的,但另一个区别是,如果你有一个双ej,(int)不会使数字变圆:5.7使用(int)的输出将是5并且如果你使用Convert.ToInt()数字将为6。

这已经讨论过,但我想分享一个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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top