C# 为什么 Int32.TryParse 在无法转换时重置 out 参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1141931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does Int32.TryParse reset the out parameter when not able to convert?
提问by Carl Bergquist
if I run this C# code
如果我运行这个 C# 代码
int realInt = 3;
string foo = "bar";
Int32.TryParse(foo, out realInt);
Console.WriteLine(realInt);
Console.Read();
I get 0. And I would like to know why! Cause I cannot find any reason why it would. This forces me to make temp variables for every parsing. So please! Great coders of the universe, enlighten me!
我得到 0。我想知道为什么!因为我找不到任何原因。这迫使我为每个解析创建临时变量。所以,请!宇宙中伟大的程序员,请赐教!
采纳答案by Marc Gravell
It is "out", not "ref". Inside the method it hasto assign it (without reading it first) to satisfy the meaning of "out".
它是“出”,而不是“参考”。在方法内部,它必须对其进行赋值(无需先阅读)以满足“out”的含义。
Actually, "out" is a languageconcern (not a framework one) - so a managed C++ implementation could probably ignore this... but it is more consistent to follow it.
实际上,“out”是一种语言问题(不是框架问题)-因此托管 C++ 实现可能会忽略这一点……但遵循它会更加一致。
In reality; if the method returns false you simply shouldn't look at the value; treat it as garbage until it is next assigned. It is stated to return 0, but that is rarely useful.
事实上; 如果该方法返回 false,则您根本不应该查看该值;将其视为垃圾,直到下一次分配为止。据说返回 0,但这很少有用。
Also - if it didn't do this (i.e. if it preserved the value); what would this print:
另外 - 如果它没有这样做(即如果它保留了价值);这会打印什么:
int i;
int.TryParse("gibber", out i);
Console.WriteLine(i);
That is perfectly valid C#... so what does it print?
这是完全有效的 C#... 那么它打印什么?
回答by gimel
The Int32.TryParse Method (String, Int32) docsays:
Int32.TryParse Method (String, Int32) 文档说:
Converts the string representation of a number to its 32-bit signed integer equivalent. A return value indicates whether the conversion succeeded.
result
Type: System.Int32
When this method returns, contains the 32-bit signed integer value equivalent to the number contained in s, if the conversion succeeded, or zero if the conversion failed. The conversion fails if the s parameter is null reference (Nothing in Visual Basic), is not of the correct format, or represents a number less than MinValue or greater than MaxValue. This parameter is passed uninitialized.
将数字的字符串表示形式转换为其等效的 32 位有符号整数。返回值指示转换是否成功。
结果
类型:System.Int32
当此方法返回时,如果转换成功,则包含与 s 中包含的数字等效的 32 位有符号整数值,如果转换失败,则为0。如果 s 参数为空引用(在 Visual Basic 中为 Nothing)、格式不正确或表示小于 MinValue 或大于 MaxValue 的数字,则转换将失败。此参数未初始化传递。
回答by Cecil Has a Name
Because (at least in C#) the method that takes one or more out parameters must guarantee that they write back to them. That way you do not need to initialize local fields in a method before passing them as out arguments to a method.
因为(至少在 C# 中)需要一个或多个 out 参数的方法必须保证它们写回它们。这样你就不需要在方法中初始化本地字段,然后再将它们作为输出参数传递给方法。
回答by codekaizen
My guess is that it's part of the C# spec:
我的猜测是它是 C# 规范的一部分:
10.5.1.3 Output parameters ... Within a method, just like a local variable, an output parameter is initially considered > unassigned and must be definitely assigned before its value is used.
Every output parameter of a method must be definitely assigned before the method returns.
10.5.1.3 输出参数……在一个方法中,就像一个局部变量一样,输出参数最初被认为是>未分配的,并且在使用其值之前必须明确分配。
方法的每个输出参数都必须在方法返回之前明确分配。
If this is the case, you shouldn't rely on the resulting value.
如果是这种情况,则不应依赖结果值。
回答by Martin Liversage
Since the second parameter to TryParse
is an out
parameter the TryParse
method is forced to initialize the parameter. Had the parameter been ref
instead of out
you would get your desired behaviour. However, since the TryParse
method only needs to ouput a number and not get any number as input out
is the proper choice for the parameter.
由于第二个参数 toTryParse
是一个out
参数,因此该TryParse
方法被迫初始化该参数。如果参数是ref
而不是out
你会得到你想要的行为。然而,由于该TryParse
方法只需要输出一个数字而不需要任何数字作为输入out
是参数的正确选择。
回答by Aamir
Because this is how the 'out' contract works. Whenever you pass an out
param to a function, its the responsibility of the function to initialize it.
因为这就是'out'合同的运作方式。每当您将out
参数传递给函数时,函数都有责任对其进行初始化。
回答by James
the MSDN documentation for Int32.TryParsestates that if the conversion fails the result will always return 0.
Int32.TryParse的 MSDN 文档指出,如果转换失败,结果将始终返回 0。
You are usually supposed to either use a temporary result variable i.e.
您通常应该使用临时结果变量,即
int value;
bool succeeded = Int32.TryParse("astring", out value);
if (succeeded)
{
// use value in some way
}
Or you just wrap the full method in an if statement
或者您只需将完整方法包装在 if 语句中
int value;
if (Int32.TryParse("astring", out value))
{
// use value in some way
}
Personally I find the latter the better option.
我个人认为后者是更好的选择。
回答by Sean
Because the parameter is an out parameter you don't have to initialize realIntwhen you declare it, since the compiler can see that you're passing it to a method that is guaranteeded to set it to something (because of the "out").
因为该参数是一个 out 参数,所以您不必在声明它时初始化realInt,因为编译器可以看到您将它传递给一个保证将其设置为某些内容的方法(因为“out”) .
Now, becuase it's an out parameter the TryParse is required to set it to something. It sets it to 0 becuase this is the default value for an int under most situations in C#.
现在,因为它是一个 out 参数,TryParse 需要将其设置为某些东西。它将它设置为 0,因为这是 C# 中大多数情况下 int 的默认值。
You could write it as:
你可以把它写成:
int realInt;
string foo="bar";
if(int.TryParse(foo,out realInt)==false)
{
realInt=3;
}
回答by Marc
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;
}
}