C#增加到管柱
我从C#/WPF添加了一个意外行为 所以,如果我得到quant为1,quant将增加到2。但是s字符串将是1。这是一个优先权问题吗 编辑: 我将此重新写为: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,
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是如何工作的(但我想这不应该有什么不同),实际的解释正如我在最初的回答中所说的。这可能就像高中物理:他们教你的东西确实能帮助你理解