C#' ++'运算符与ToString()一起使用

时间:2016-07-05 18:44:09

标签: c# .net clr

我需要在linqpad中验证这一点,但这段代码第一次评估为0。为什么会在C#中出现?

var integer = 0;
while(true){
    var @string = integer++.ToString();
    Console.WriteLine(@string);
}

我还验证首先评估为1。

var integer = 0;
while(true){
    var @string = (++integer).ToString();
    Console.WriteLine(@string);
}

我得到了++ x和x ++之间的区别。只是期望它做x ++然后调用ToString()。

4 个答案:

答案 0 :(得分:1)

我对post增量运算符的理解是它首先保存变量的值(在这种情况下为i),递增i然后使用保存的值(在本例中,在致电ToString())。

此代码:

int i = 5;
string s = i++.ToString();

相当于:

int i = 5;
int temp = i;
i = i + 1;
var s = temp.ToString();

您可以使用LinqPad或其他工具(ILSpy等)查看IL:

IL_0000:  nop         
IL_0001:  ldc.i4.5    
IL_0002:  stloc.0     // i
IL_0003:  ldloc.0     // i
IL_0004:  dup         
IL_0005:  ldc.i4.1    
IL_0006:  add         
IL_0007:  stloc.0     // i
IL_0008:  stloc.2     // CS$0$0000
IL_0009:  ldloca.s    02 // CS$0$0000
IL_000B:  call        System.Int32.ToString
IL_0010:  stloc.1     // s
IL_0011:  ret         

这里有一个blog post by Eric Lippert,其中包含更多信息

答案 1 :(得分:1)

从根本上说,table-cell.nav运算符的行为与调用以++作为参数的任何其他函数时的行为没有区别。例如,如果您调用i++.ToString(),则完全可以期望传递i的原始值。

例如,考虑一个扩展方法:

i

现在,可以将其称为实例方法:

SomeFunction(i++)

编译器将其转换为对静态public static class GoofyExtensions { public static string Frob(this int x) { return x.ToString(); } } 方法的调用:

var s = i++.Frob();

发现Frob返回的值与var s = GoofyExtensions.Frob(i++); 不同,会非常令人惊讶。

这里的要点是虽然i++.Frob()是一个没有参数的方法,但内部所有实例方法都有一个隐含参数:实例。如果检查生成的MSIL,您将看到对实例的引用作为参数传递给所有实例方法。因此,i++.ToString()在非常真实的意义上是对ToString()的调用。

答案 2 :(得分:0)

https://msdn.microsoft.com/en-us/library/6a71f45d.aspx

++的后缀版本返回整数的值然后递增,而++增量的前缀版本则返回。因此,在这两种情况下,您都在返回值上调用ToString,但运算符的位置决定了返回的值。

答案 3 :(得分:0)

这两个运算符(后缀和前缀)都充当函数。它们在对其参数执行操作后返回值,在本例中为integer。这是非常规的,但它正在做什么。

基本上,你正在做:

var @string = postfixplusplus(integer).ToString();

我希望这种思维方式能够解释一下。

相关问题