[英]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.