在声明点使用变量作为out参数

dal*_*lle 15 c# out language-lawyer

在阅读对答案的评论时,我看到了以下构造来声明和初始化变量:

int variable = int.TryParse(stringValue, out variable) ? variable : 0;
Run Code Online (Sandbox Code Playgroud)

在C#中这是允许的,正确的和明确定义的吗?引擎盖下会发生什么?以下是怎么回事?

  1. variable第一初始化为零?
  2. 然后传递给int.TryParse(赋值)?
  3. 然后可选择阅读(如果int.TryParse返回true)?
  4. 然后,再次分配/初始化?

D J*_*D J 10

是的,你是正确的执行.您还可以查看此处生成的MSIL

C#代码

 string stringValue = "5";
 int variable = int.TryParse(stringValue, out variable) ? variable : 0;
Run Code Online (Sandbox Code Playgroud)

MSIL生成

1.  IL_0000:  nop    
2.  IL_0001:  ldstr      "5" // load string
3.  IL_0006:  stloc.0
4.  IL_0007:  ldloc.0
5.  IL_0008:  ldloca.s   variable
6.  IL_000a:  call       bool [mscorlib]System.Int32::TryParse(string, int32&)
7.  IL_000f:  brtrue.s   IL_0014
8.  IL_0011:  ldc.i4.0
9.  IL_0012:  br.s       IL_0015
10. IL_0014:  ldloc.1
11. IL_0015:  stloc.1
12. IL_0016:  ret
Run Code Online (Sandbox Code Playgroud)

这澄清了它在幕后的作用.

声明5将变量分配到堆栈.声明6称之为方法.声明7,8,9实际上是在表达bool表达式.


ang*_*son 8

这是一个恰好起作用的技巧,因为它只是重写普通的if语句.这段代码相当于:

int variable;
if (int.TryParse(stringVariable, out variable))
    variable = variable;
else
    variable = 0;
Run Code Online (Sandbox Code Playgroud)

顺序如下:

int.TryParse被调用,variable在此之前没有被初始化,但它也没有.一个out参数不需要一个明确的赋值的变量.作为方法执行的一部分,variable将给出一个值,int.TryParse并将返回truefalse.

如果方法返回true那么表达式的结果 将是variable,因此我们将基本执行variable = variable.

如果该方法返回,false那么表达式的结果 将改为0,并且variable现在将给出值,0而不管它作为一部分给出的是什么int.TryParse.但是,在这种情况下,这不会更改变量,因为在返回时int.TryParse已经给出了variable一个默认值,false这也是正确的0.

这基本上是将一切都放在一条线上的方法.

就个人而言,我会像这样编写这样的代码:

int variable;
int.TryParse(stringValue, out variable);
Run Code Online (Sandbox Code Playgroud)


Aza*_*Aza 5

int variable声明variable,并且out variable必须初始化它.这两件事必须在variable任何地方使用之前发生,并且由于out声明,这是正确的.

正如Lasse V. Carlsen所指出的,来自TryParse的文档,TryParse默认情况下会为其指定0转换失败的值:

当此方法返回时,[ return]包含等效于s中包含的数字的32位有符号整数值(如果转换成功),或者如果转换失败则为零.(我的)

如果你扩展三元函数,你会看到:

int variable;
if (int.TryParse(stringValue, out variable))
    variable = variable;
else
    variable = 0;
Run Code Online (Sandbox Code Playgroud)

这本身就是一种法律表达.这两条路径是:

  • TryParse将值赋给variable并返回true,从而导致赋值variable给它自己
  • TryParse初始化variable0并返回false,导致variable由三元条件赋值为零

但是,这不是特别清晰的代码,我不建议这样做.

  • 实际上,如果`TryParse`返回`false`,它仍然必须设置`variable`,在这种情况下它是[记录](https://msdn.microsoft.com/en-us/library/f02979c7(v = vs.110).aspx)初始化为"0":当此方法返回时,包含等效于s中包含的数字的32位有符号整数值,如果转换成功,则为**或如果转换失败则为零.***(我的重点)* (2认同)