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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:13:43  来源:igfitidea点击:

Why does Int32.TryParse reset the out parameter when not able to convert?

c#

提问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 TryParseis an outparameter the TryParsemethod is forced to initialize the parameter. Had the parameter been refinstead of outyou would get your desired behaviour. However, since the TryParsemethod only needs to ouput a number and not get any number as input outis 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 outparam 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;
    }
}