以下代码抛出编译时错误,如
无法将'string'类型转换为'int'
string name = Session["name1"].ToString();
int i = (int)name;
而下面的代码编译并成功执行:
string name = Session["name1"].ToString();
int i = Convert.ToInt32(name);
我想知道:
为什么第一个代码会产生编译时错误?
2个代码段之间有什么区别?
答案 0 :(得分:62)
(int)foo
只是对Int32
(C#中的int
)类型的强制转换。这内置于CLR中,并要求foo
为数字变量(例如float
,long
等。)从这个意义上讲,它与C中的强制转换非常相似。 / p>
Convert.ToInt32
旨在成为一般转化功能。它比铸造做得更好;也就是说,它可以从任何基元类型转换为int
(最值得注意的是,解析string
)。您可以看到此方法的完整重载列表here on MSDN。
正如Stefan Steiger提及in a comment:
另请注意,在数字级别上,
(int) foo
截断foo
(ifoo = Math.Floor(foo)
),而Convert.ToInt32(foo)
使用half to even rounding(将x.5舍入到最接近的EVEN整数,表示ifoo = Math.Round(foo)
)。因此,结果不仅仅是实施方式,而且数字不相同。
答案 1 :(得分:18)
(这一行涉及合并的问题)你永远不应该使用(int)someString
- 这将永远不会起作用(编译器不会让你)。
然而,int int.Parse(string)
和bool int.TryParse(string, out int)
(及其各种超载)是合理的游戏。
就个人而言,我主要在我处理反射时只使用Convert
,所以对我来说,选择是Parse
和TryParse
。第一个是当我期望该值为有效整数时,并希望它抛出异常。第二个是当我想检查它是否是一个有效的整数时 - 我可以决定当它是/不是时该做什么。
答案 2 :(得分:5)
Cast意味着两个相互矛盾的事情:“检查这个对象是否真的属于这种类型,如果不是则抛出”并且“此对象不属于给定类型;找到属于给定类型的等效值”
所以你在1.)中试图做的是声明是一个String是一个Int。但是由于String不是int,因此断言失败。
2.)成功的原因是因为Convert.ToInt32()解析字符串并返回一个int。它仍然可能失败,例如:
Convert.ToInt32("Hello");
会导致Argument异常。
总而言之,从String转换为Int是一个框架问题,而不是.Net类型系统中隐含的东西。
答案 3 :(得分:4)
无法通过显式转换将字符串强制转换为int。必须使用int.Parse
转换它。
Convert.ToInt32基本上包装了这个方法:
public static int ToInt32(string value)
{
if (value == null)
{
return 0;
}
return int.Parse(value, CultureInfo.CurrentCulture);
}
答案 4 :(得分:4)
您正在谈论C#转换操作与.NET转换实用程序
(Casting)语法适用于数字数据类型,也适用于“兼容”数据类型。兼容意味着通过继承(即基础/派生类)或通过实现(即接口)建立关系的数据类型。
转换也可以在定义了conversion operators的不同数据类型之间工作。
另一方面, System.Convert 类是一般意义上转换事物的许多可用机制之一;它包含在不同的,已知的,可以在逻辑上从一种形式更改为另一种形式的数据类型之间进行转换的逻辑。
通过允许在类似数据类型之间进行转换,转换甚至涵盖了一些与转换相同的基础。
请记住,C#语言有自己做某些事情的方式 除了任何编程语言之外,底层.NET Framework还有自己的处理方式 (有时他们的意图重叠。)
将转换视为C#语言级别的功能,本质上更受限制,并通过System.Convert类转换为.NET框架中的许多可用机制之一,以便在不同类型之间转换值。
答案 5 :(得分:1)
1)C#是类型安全的语言,不允许您将字符串分配给数字
2)第二种情况将字符串解析为新变量。 在你的情况下,如果Session是ASP.NET会话,那么你不必在那里存储字符串,并在检索
时将其转换回来int iVal = 5;
Session[Name1] = 5;
int iVal1 = (int)Session[Name1];
答案 6 :(得分:1)
.NET中没有从字符串到int的默认转换。您可以使用int.Parse()或int.TryParse()来执行此操作。或者,正如您所做的那样,您可以使用Convert.ToInt32()。
但是,在您的示例中,为什么要使用ToString()然后将其转换回int?您可以简单地将int存储在Session中并按如下方式检索它:
int i = Session["name1"];
答案 7 :(得分:1)
只是一个简短的额外:在不同的情况下(例如,如果你正在转换双倍,& c转换为Int32),你可能还想在选择这两者时担心舍入。 Convert.Int32将使用银行家的舍入(MSDN); (int)将截断为整数。
答案 8 :(得分:0)
Convert.ToInt32
return int.Parse(value, CultureInfo.CurrentCulture);
但是(int)是类型转换,因此(int)“2”将无法工作,因为您无法将字符串转换为int。但是你可以像Convert.ToInt32那样解析它
答案 9 :(得分:0)
不同之处在于第一个片段是强制转换,第二个片段是转换。虽然,我认为编译错误可能因为措辞而在这里提供更多的混淆。也许如果它说“不能将类型'字符串'转换为'int'会更好。
答案 10 :(得分:0)
这是旧的,但另一个区别是,如果你有一个双ej,(int)不会使数字变圆:5.7使用(int)的输出将是5并且如果你使用Convert.ToInt( )这个数字将会变为6。
答案 11 :(得分:0)
已经讨论过了,但是我想分享一个dotnetfiddle。
如果要处理算术运算并使用浮点,小数,双精度等,则最好使用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