c# & # 39; + + & # 39;操作符与ToString()结合使用

本文关键字:结合 操作符 ToString | 更新日期: 2023-09-27 17:54:57

我需要在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++然后ToString()被调用

c# & # 39; + + & # 39;操作符与ToString()结合使用

我对后增量运算符的理解是,它首先保存变量的值(在本例中为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         

这里是Eric Lippert的博客文章,提供更多信息

基本上,i++.ToString()++运算符的行为与调用任何其他以i为参数的函数时的行为没有什么不同。例如,如果调用SomeFunction(i++),则完全可以期望传递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()返回的值与i++.ToString()不同,那将是相当令人惊讶的。

这里的要点是,尽管ToString()是一个没有参数的方法,但在内部所有实例方法都有一个隐式参数:instance。如果检查生成的MSIL,将看到对实例的引用作为参数传递给所有实例方法。所以i.ToString()实际上是对Int32.ToString(i)的调用

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

后缀版本的++先返回整型的值,然后加1,而前缀版本的++先加1,然后返回。在这两种情况下你都在返回值上调用ToString,但是运算符的位置决定了返回哪个值

后缀和前缀这两个操作符都充当函数。它们在对参数执行操作后返回一个值,在本例中是integer。它看起来很不传统,但这就是它所做的。

基本上,你在做:

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

我希望这种思考方式能解释一点。