C# 递增 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();
现在这按我的预期工作。
I add an unexpected behaviour from 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;
}
}
So, if I get quant as 1, quant will be incremented to 2. But the s string will be 1. Is this a question of precedence?
EDIT:
I re-wrote this as:
quant++;
Qnt.Text = quant.ToString();
and now this works as I expected.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您正在使用post-增量运算符。这会计算出原始值,然后递增。要在一行中执行您想要的操作,您可以使用预增量运算符。
但更好的是避免所有这些陷阱并这样做:
对于第一个版本,您必须考虑事情发生的顺序。在第二个版本中不需要思考。始终更重视代码的清晰度而不是简洁性。
人们很容易相信单行版本在某种程度上更快,但事实并非如此。在 20 世纪 70 年代的 C 系统中,这可能是正确的,但即便如此,我对此表示怀疑。
You are using the post-increment operator. This evalutates to the original value, and then increments. To do what you want in a one-liner you can use the pre-increment operator instead.
But even better would be to avoid all such pitfalls and do it like this:
With the first version you have to think about the order in which things happen. In the second version no thought is required. Always value code clarity more highly than conciseness.
It's easy to believe that the one-line version is somehow faster, but that's not true. It might have been true back in the day in 1970s C systems, but even then that I doubt.
问题是您使用的是后增量而不是前增量...但是为什么您要编写这段复杂的代码呢?只需将副作用(增量)和 ToString 调用分开:
或者甚至放弃实际的增量,因为您不会再次读取该值:
在可能的情况下,避免em> 在其他表达式中间使用复合赋值。它通常会导致疼痛。
此外,感觉所有这些解析和格式化都隐藏了真实的模型,也就是说,某处应该有一个
int
属性,这可能反映在 UI 中。例如:The problem is that you're using a post-increment instead of a pre-increment... but why would you want to write this convoluted code? Just separate out the side-effect (incrementing) and the ToString call:
Or even forego the actual increment given that you're not going to read the value again:
Where possible, avoid using compound assignment in the middle of other expressions. It generally leads to pain.
Additionally, it feels like all this parsing and formatting is hiding the real model, which is that there should be an
int
property somewhere, which might be reflected in the UI. For example:现在我会做一些不应该做的事情...我会尝试简化 Eric Lippert 在这里写的内容 i++ 和 ++i 之间有什么区别? 我希望我没有写太多错误的东西:-)
现在...前自增和后自增运算符的作用是什么?简化并忽略中间完成的所有复制(并记住它们在多线程环境中不是原子运算符):
它们都是表达式(例如
i + 1< /code>)返回结果(如
i + 1
),但有副作用(与i + 1
不同)。副作用是它们增加了变量i
。最大的问题是“一切按什么顺序发生?”答案很简单:i
的新值++i
:增量增量
i++
:增量i
并返回i
的旧值现在...重要的部分是
增量 i
总是首先发生。然后返回一个值(旧的或新的)。让我们举一个例子(Lippert 的例子相当复杂。我会做一个不同的、更简单的例子,虽然不是那么完整,但足以检查我之前说的顺序是否正确)(技术上)我将举两个例子)
示例 1:
示例 2:
checked
表示如果存在溢出,将抛出异常 (OverflowException
)。unchecked
意味着相同的操作不会抛出异常。Int32.MaxValue + 1
肯定会溢出。如果选中
,则会出现异常,如果未选中
,则i
将变为-1。让我们尝试运行第一个代码段。结果:
好的...
i
增加了,但Console.WriteLine
收到了旧值 (Int32.MaxValue == 2147483647
)。从这个例子中我们无法确定后递增和调用Console.WriteLine的顺序。让我们尝试运行第二个代码段。结果:
好的...很明显,首先执行了后置增量,引发了异常,然后显然
Console.WriteLine
没有执行(因为程序结束了)。所以我们知道我说的顺序是正确的。
现在。你应该从这个例子中学到什么?这和我很多年前学到的一样。 C 和 C# 中的前后增量非常适合混淆代码竞赛。它们不适用于许多其他事情(但请注意,C++ 不同!)。从那次教训中我了解到,可以自由使用后自增的地方正好有两个,可以自由使用前自增的地方正好有零个。
“安全”后增量
和
“安全”前增量
Now I'll do something that shouldn't be done... I'll try to simplify what Eric Lippert wrote here What is the difference between i++ and ++i? I hope I'm not writing anything too much wrong :-)
Now... What does the pre-increment and post-increment operators do? Simplifying and ignoring all the copy that are done in-between (and remembering that they aren't atomic operators in multi-threaded environments):
both of them are expressions (like
i + 1
) that return a result (likei + 1
) but that have a side-effect (unlikei + 1
). The side-effect is that they increment the variablei
. The big question is "in which order everything happens?" The answer is quite simple:++i
: incrementsi
and returns the new value ofi
i++
: incrementsi
and returns the old value ofi
Now... The important part is that the
increments i
always happens first. Then a value (the old or the new) is returned.Let's make an example (the example of Lippert is quite complex. I'll make a different, more simple example, that isn't as much complete but that is enough to check if the order I said before is right or not) (technically I'll make two examples)
Example 1:
Example 2:
checked
means that if there is an overflow an exception (OverflowException
) will be thrown.unchecked
means that the same operation won't throw an exception.Int32.MaxValue + 1
surely will overflow. Withchecked
there will be an exception, withunchecked
i
will become -1.Let's try running the first code piece. Result:
Ok... The
i
was incremented but theConsole.WriteLine
received the old value (Int32.MaxValue == 2147483647
). From this example we can't determine the order of the post-increment and of the calling ofConsole.WriteLine
.Let's try running the second code piece. Result:
Ok... It's quite clear that first the post-increment was executed, caused an exception, and then clearly the
Console.WriteLine
wasn't executed (because the program ended).So we know that the order I said is the right one.
Now. What should you learn from this example? The same thing I learned many years ago. Pre and post increments in C and C# are good for obfuscated code contests. They aren't good for many other things (but note that C++ is different!). From that lesson I learned that there are exactly two places where you can use post-increment freely, and there are exactly zero places where you can use pre-increment freely.
"Safe" post-increment
and
"Safe" pre-increment
在这种情况下,首先将调用
quant.ToString()
,然后 quant 将递增。如果您编写
((++quant).ToString())
,第一步将递增 quant,然后调用quant.ToString()
。In this case, first
quant.ToString()
will be called and then quant will be incremented.If you write
((++quant).ToString())
the first step will be incrementing quant and thenquant.ToString()
will be called.string s = ((quant++).ToString());
可以分发为
在递增之前使用
quant
调用 toString() 方法,然后执行赋值运算符,然后
增加 `quant'
尝试使用 ++quant。
string s = ((quant++).ToString());
can be distributed as
use
quant
for toString() method call before incrementing, and thenexecute assignment operator, and then
increment `quant'
try with ++quant.