繁体   English   中英

C#递增ToString

[英]C# increment ToString

我在C#/ WPF中添加了一个意外的行为

    private void ButtonUp_Click(object sender, RoutedEventArgs e)
    {
        int quant;
        if( int.TryParse(Qnt.Text, out quant))
        {
            string s = ((quant++).ToString());
            Qnt.Text = s;
        }
    }

因此,如果我将quant设为1,则quant将增加到2.但s字符串将为1.这是优先级问题吗?

编辑:

我把它重写为:

            quant++;
            Qnt.Text = quant.ToString();

现在这可以按照我的预期运作。

问题是你使用的是后增量而不是预增量...但为什么编写这个复杂的代码呢? 只需将副作用(递增)和ToString调用分开:

if (int.TryParse(Qnt.Text, out quant))
{
    quant++;
    Qnt.Text = quant.ToString();
}

或者甚至放弃实际增量,因为你不会再次读取该值:

if (int.TryParse(Qnt.Text, out quant))
{
    Qnt.Text = (quant + 1).ToString();
}

尽可能避免在其他表达式的中间使用复合赋值。 它通常会导致疼痛。

另外,感觉所有这些解析和格式化都隐藏了真实模型,即某处应该有一个int属性,这可能会反映在UI中。 例如:

private void ButtonUp_Click(object sender, RoutedEventArgs e)
{
    // This is an int property
    Quantity++;
    // Now reflect the change in the UI. Ideally, do this through binding
    // instead.
    Qnt.Text = Quantity.ToString();
}

您正在使用post -increment运算符。 这将重新评估原始值,然后递增。 要在单行中执行您想要的操作,您可以使用pre -increment运算符。

(++quant).ToString();

但更好的方法是避免所有这些陷阱并像这样做:

quant++;
string s = quant.ToString();

在第一个版本中,您必须考虑事情发生的顺序。 在第二个版本中,不需要考虑。 始终比简洁更重视代码清晰度。

很容易相信单行版本在某种程度上更快,但事实并非如此。 在20世纪70年代的C系统中,这可能是真的,但即便如此,我也怀疑。

现在我会做一些不应该做的事情...我会尝试简化Eric Lippert在这里写的内容i ++和++ i之间的区别是什么? 我希望我写的不是太多错了:-)

现在......预增量和后增量运算符有什么作用? 简化并忽略在中间完成的所有副本(并记住它们不是多线程环境中的原子操作符):

它们都是表达式(如i + 1 )返回结果(如i + 1 )但有副作用(与i + 1不同)。 副作用是它们增加变量i 最大的问题是“一切都发生在哪个顺序?” 答案很简单:

  • 预递增++i :增量i和返回的i
  • 后递增i++ :递增i并返回i

现在......重要的是, increments i总是首先发生increments i 然后返回一个值(旧的或新的)。

让我们举一个例子(Lippert的例子非常复杂。我将做一个不同的,更简单的例子,它不是那么完整,但足以检查我之前说过的顺序是否正确)(技术上)我会做两个例子)

例1:

unchecked
{
    int i = Int32.MaxValue;
    Console.WriteLine("Hello! I'm trying to do my work here {0}", i++);
    Console.WriteLine("Work done {1}", i);
}

例2:

checked
{
    int i = Int32.MaxValue;
    Console.WriteLine("Hello! I'm trying to do my work here {0}", i++);
    Console.WriteLine("Work done {1}", i);
}

checked表示如果有溢出,则抛出异常( OverflowException )。 unchecked意味着相同的操作不会抛出异常。 Int32.MaxValue + 1肯定会溢出。 checked会出现异常,如果unchecked i将变为-1。

让我们尝试运行第一个代码片段。 结果:

Hello! I'm trying to do my work here 2147483647
Work done -1

好的... i增加但Console.WriteLine收到旧值( Int32.MaxValue == 2147483647 )。 从这个例子中我们无法确定后增量和调用Console.WriteLine的顺序。

让我们尝试运行第二个代码片段。 结果:

System.OverflowException: Arithmetic operation resulted in an overflow.

好的......很明显,首先执行后增量,导致异常,然后显然没有执行Console.WriteLine (因为程序结束)。

所以我们知道我说的顺序是正确的。

现在。 你应该从这个例子中学到什么? 我多年前学到的一样。 C和C#中的前后增量适用于模糊代码竞争。 它们对许多其他东西并不好(但请注意C ++是不同的!)。 从那一课我了解到,正好有两个地方你可以自由地使用后增量,而且你可以自由地使用预增量。

“安全”后增量

for (int i = 0; i < x; i++)

i++; // Written alone. Nothing else on the same line but a comment if necessary.

“安全”预增量

(nothing)

在这种情况下,首先quant.ToString()然后递增quant。

如果你写((++quant).ToString()) ,第一步是递增quant,然后quant.ToString()

string s = ((quant++).ToString());

可以分发为

在递增之前使用quant for toString()方法调用,然后使用

执行赋值运算符,然后

增量`quant'

试试++ quant。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM