簡體   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