在question的背面稍微询问out
参数的行为,但更关注为什么这些TryParse
方法使用out
而不是{{} 1}}。
在某些情况下,您确实希望在解析之前初始化参数的值,并在解析失败时保留该值但不关心它是否失败。但是由于ref
参数,值将被重置。
这种情况看起来像这样......
out
但是由于int arg = 123;
Int32.TryParse(someString, ref arg);
参数,我们必须像这样编写它,这更详细......
out
我意识到知道解析失败可能非常有用,但使用int arg;
if(!Int32.TryParse(someString, out arg)
{
arg = 123;
}
并不排除这一点。
那么为什么这些TryParse方法使用ref
而不是out
?
答案 0 :(得分:13)
因为正常使用模式与您所描述的完全相反。
人们应该能够写
int arg;
if (!Int32.TryParse(someString, ref arg)) {
Waaah;
}
如果TryParse
采用ref
参数,则需要无用的初始化。
真正的问题是为什么没有int? int.TryParse(string)
方法。
答案 1 :(得分:5)
您使用out
表示该参数未被使用,仅设置。调用者必需在方法返回之前分配值:
int n;
if (Int32.TryParse("47", out n)) { // Works fine; `n` will be set to the
// .. // result of the parse.
}
如果您使用ref
,则必须事先初始化该值,这很愚蠢,因为它会被覆盖:
int n;
if (Int32.TryParse("47", ref n)) { // Kablammo! `n` isn't initialized.
// ..
}
这正是TryParse的要点:保证在out
参数中有一个代表解析尝试输出的值。返回值true或false表示您是否应该关心结果或忽略它。
答案 2 :(得分:3)
这是因为out
参数更适合该方法。
如果它使用了ref
参数,那么有来为该方法提供输入。这不起作用:
int arg;
if (Int32.TryParse(someString, ref arg)) { // error - variable is not initialsed
该方法不期望值参数中的任何输入,如果您必须提供输入值,那将是什么,或者如何使用它不明显。
答案 3 :(得分:0)
根据我的经验,当你不想打扰初始化时,还有很多次你想要提供默认值。 Parse的设计考虑到了这一点。
这个问题很好,我不认为使用一种方法或另一种方法存在严重问题。 .NET团队选择了out方法,因为如果不向int添加单独的方法,他们就无法使用这两种方法,这将是令人厌恶的冗余。