C#增加到管柱

C#增加到管柱,c#,tostring,increment,operator-precedence,C#,Tostring,Increment,Operator Precedence,我从C#/WPF添加了一个意外行为 所以,如果我得到quant为1,quant将增加到2。但是s字符串将是1。这是一个优先权问题吗 编辑: 我将此重新写为: quant++; Qnt.Text = quant.ToString(); 现在,这正如我所期望的那样起作用。问题是,您使用的是后期增量而不是预增量。。。但是你为什么要写这些复杂的代码呢?只需将副作用(递增)和ToString调用分开: if (int.TryParse(Qnt.Text,

我从C#/WPF添加了一个意外行为

所以,如果我得到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();
}
您正在使用后增量运算符。该值计算为原始值,然后递增。要在单行程序中执行所需操作,可以使用pre-increment操作符

(++quant).ToString();
但更好的办法是避免所有这些陷阱,并这样做:

quant++;
string s = quant.ToString();
对于第一个版本,你必须考虑事情发生的顺序。在第二个版本中,不需要考虑。始终重视代码的清晰性,而不是简洁性


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

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

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

字符串s=((quant++).ToString())

可作为

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

执行赋值运算符,然后

增量'quant'


尝试使用++quant。

现在我将做一些不应该做的事情。。。我会尽量简化Eric Lippert在这里写的内容我希望我没有写太多错误:-)

现在。。。增量前和增量后运算符的作用是什么?简化并忽略在这段时间内完成的所有复制(记住它们在多线程环境中不是原子操作符):

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

  • 递增前
    ++i
    :递增
    i
    并返回
    i
  • 增量后
    i++
    :增量
    i
    并返回
    i
现在。。。重要的一点是,
增量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);
}
选中
表示如果存在溢出,将抛出异常(
OverflowException
)<代码>未选中表示同一操作不会引发异常
Int32.MaxValue+1肯定会溢出。选中
时将出现异常,未选中
i
将变为-1

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

你好!我想在这里工作2147483647
完成的工作-1
好的。。。
i
已递增,但
控制台.WriteLine
收到旧值(
Int32.MaxValue==2147483647
)。从这个示例中,我们无法确定后期增量和调用
控制台.WriteLine
的顺序

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

System.OverflowException:算术运算导致溢出。
好的。。。很明显,首先执行了post增量,导致了异常,然后显然没有执行
控制台.WriteLine
(因为程序结束)

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

现在。你应该从这个例子中学到什么?和我多年前学到的一样。C和C#中的前置和后置增量适用于模糊代码竞赛。它们对很多其他事物都不好(但是注意C++是不同的!)从这一课中,我学到了有两个地方可以自由使用后增量,也有零个地方可以自由使用前增量

“安全”后增量

for (int i = 0; i < x; i++)
(nothing)
“安全”预增量

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

试着读一下:我很抱歉问了这么一个基本的问题。这是C和C++的基本知识,引自链接
,而且,C#的工作方式与C的工作方式不同
,因此在我的C/C++学习期间,我做了无数的语句,如printf(“I:%d”,I++);所以我真的很惭愧。False,在调用该方法之前读取增量(并保存在原始变量中),但该方法仍然接收“旧”值。正如Lipper所说,这是一个常见错误,许多书(遗憾地)都没有指出。True。有人教我Java是如何工作的(但我想这不应该有什么不同),实际的解释正如我在最初的回答中所说的。这可能就像高中物理:他们教你的东西确实能帮助你理解