如果我运行此C#代码为什么Int32.TryParse在无法转换时重置out参数?
int realInt = 3;
string foo = "bar";
Int32.TryParse(foo, out realInt);
Console.WriteLine(realInt);
Console.Read();
我得到0。而且我想知道为什么!因为我找不到任何原因。这迫使我为每个解析创建临时变量。所以,请!伟大的宇宙编码者,赐教!
如果我运行此C#代码为什么Int32.TryParse在无法转换时重置out参数?
int realInt = 3;
string foo = "bar";
Int32.TryParse(foo, out realInt);
Console.WriteLine(realInt);
Console.Read();
我得到0。而且我想知道为什么!因为我找不到任何原因。这迫使我为每个解析创建临时变量。所以,请!伟大的宇宙编码者,赐教!
它是“out”,而不是“ref”。在该方法内部,具有来分配它(不先读取它)以满足“out”的含义。
实际上,“out”是一个语言问题(不是框架之一) - 所以托管的C++实现可能会忽略这个......但是它更符合它的要求。
实际上,如果该方法返回false,则不应该查看该值;将其视为垃圾直到下一次分配。它声明返回0,但这是很少有用的。
此外 - 如果它没有这样做(即如果它保存了值);这个打印:
int i;
int.TryParse("gibber", out i);
Console.WriteLine(i);
这是完全有效的C#...所以它打印什么?
*为什么*它是这样的解释,以便您可以断言在TryParse调用后的任何代码中变量* always *都已设置,即使变量在代码的前面没有初始化(所以编译器在`TryParse`调用之后使用该变量时不会引发错误;尝试对使用`ref`关键字的函数执行相同操作。) – Blixt 2009-07-17 08:16:42
The Int32.TryParse Method (String, Int32) doc说:
一个数字的字符串表示形式转换为它的32位带符号整数等效。返回值指示转换是否成功。
结果
类型:System.Int32
此方法返回时,包含32位带符号整数的值等效于包含在S中的号码,如果转换成功,或者零,如果转换失败。如果s参数为空引用(在Visual Basic中为Nothing),格式不正确,或者表示小于MinValue或大于MaxValue的数字,则转换将失败。此参数未经初始化传递。
@Luke - look以粗体显示... – 2009-07-17 08:08:02
因为(至少在C#中)带有一个或多个输出参数的方法必须保证它们回写给它们。这样,在将方法作为参数传递给方法之前,您不需要在方法中初始化本地字段。
我的猜测是,这是在C#规范的一部分:
10.5.1.3输出参数 ... 在方法内部,就像一个局部变量,输出参数最初考虑>未分配必须在使用其值之前明确分配。
在方法返回之前,方法的每个输出参数都必须明确赋值。
如果是这种情况,您不应该依赖结果值。
由于TryParse
的第二个参数是out
参数,因此TryParse
方法被强制初始化参数。如果参数是ref
而不是out
,您将得到您想要的行为。但是,由于TryParse
方法只需要输出一个数字,并且不会获得任何数字,因此输入out
是参数的正确选择。
因为这是'out'合同的工作方式。每当你将一个out
参数传递给一个函数时,它的函数的责任就是初始化它。
为Int32.TryParse MSDN文档指出,如果转换失败,结果将始终返回0
你通常应该要么使用一个临时结果变量即
int value;
bool succeeded = Int32.TryParse("astring", out value);
if (succeeded)
{
// use value in some way
}
,或者你只是包裹在if语句中完整的方法
int value;
if (Int32.TryParse("astring", out value))
{
// use value in some way
}
我个人认为后者是更好的选择。
由于该参数是一个输出参数,所以当您声明它时,您不必初始化realInt,因为编译器可以看到您将它传递给一个保证将其设置为某事的方法(因为的“出”)。
现在,因为它是一个输出参数,所以需要TryParse将其设置为某个值。它将它设置为0,因为这是C#中大多数情况下int的默认值。
你可以写为:
int realInt;
string foo="bar";
if(int.TryParse(foo,out realInt)==false)
{
realInt=3;
}
public static class IntHelper
{
public static bool TryParse(string s, ref int outValue)
{
int newValue;
bool ret = int.TryParse(s, out newValue);
if (ret) outValue = newValue;
return ret;
}
}
我格式化代码为您服务。下一次,如果您不确定如何在MarkDown编辑器中设置格式,请使用文本区域上方的小工具栏。有一个代码格式化选项。 – OregonGhost 2009-07-17 08:31:40
感谢您的帮助=) – 2009-07-17 08:49:00