如何判斷字串是否為空白串?[C#]

來源:互聯網
上載者:User

如何判斷字串是否為空白串?[C#]

 

Written by Allen Lee

 

0. 緣起:

本文寫作緣起於阮的討論——《FxCop告訴我,檢查一個字串是否為空白要用string.Length。》。其實用過FxCop的人都知道它會建議你使用String.Length屬性來判斷字串是否為空白串,但你又是否明白其中的緣由呢?今天有點閑,特意寫下這篇文章,希望有點協助。

1. 三種常用的字串判空串方法:

  • Length法:bool isEmpty = (str.Length == 0);
  • Empty法:bool isEmpty = (str == String.Empty);
  • General法:bool isEmpty = (str == "");

2. 深入內部機制:

  • 要探討這三種方法的內部機制,我們得首先看看.NET是怎樣實現的,也就是要看看.NET的原始碼!然而,我們哪裡找這些原始碼呢?我們同樣有三種方法:

    • Rotor法:一個不錯的選擇就是微軟的Rotor,這是微軟的一個原始碼共用項目。
    • Mono法:另一個不錯的選擇當然就是真正的開源項目Mono啦!
    • Reflector法:最後一個選擇就是使用反編譯器,不過這種重組的代碼不一定就是原貌,只不過是一種“近似值”,你可以考慮使用Reflector這個反編譯器[1]。
  • 這裡我採用Reflector法,我們先來看看一下原始碼[2](片段):

public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable, IComparablestring>
{
    static String()
    {
        string.Empty = "";

        // Code here
    }

    // Code here

    public static readonly string Empty;

    public static bool operator ==(string a, string b)
    {
        return string.Equals(a, b);
    }

    public static bool Equals(string a, string b)
    {
        if (a == b)
        {
            return true;
        }
        if ((a != null) && (b != null))
        {
            return string.EqualsHelper(a, b);
        }
        return false;
    }

    private static unsafe bool EqualsHelper(string ao, string bo)
    {
        // Code here

        int num1 = ao.Length;
        if (num1 != bo.Length)
        {
            return false;
        }
        
        // Code here
    }

    private extern int InternalLength();

    public int Length
    {
        get
        {
            return this.InternalLength();
        }
    }

    // Code here
}
  • Rotor裡面String類的代碼與此沒什麼不同,只是沒有EqualsHelper方法,代之以如下的聲明:

public extern bool Equals(String value);
  • 進一步分析:

    • 首先是Empty法,由於String.Empty是一個靜態唯讀域,只會被建立一次(在靜態建構函式中)。但當我們使用Empty法進行判空時,.NET還會依次展開調用以下的方法,而後兩個方法內部還會進行對象引用判等!

public static bool operator ==(string a, string b);

public static bool Equals(string a, string b);

private static unsafe bool EqualsHelper(string ao, string bo);
    • 若使用General法判等的話,情況就“更勝一籌”了!因為.NET除了要依次展開調用上面三個方法之外,還得首先建立一個臨時的Null 字元串執行個體,如果你要進行大量的比較,這恐怕是想一想就很嚇人了!
    • 而對於Length法,我們就可以繞過上面這些繁瑣的步驟,直接進行整數(字串長度)判等,我們知道,大多數情況下,整數判等都要來得快(我實在想不出比它更快的了,在32位系統上,System.Int32運算最快了)!
    • 另外,我們還可以看到,在EqualsHelper方法裡面.NET會先使用Length法來進行判等!可惜的是我無法獲得InternalLength方法的代碼。但我在Mono的原始碼裡面看到更簡明的實現:

class String 
{
    private int length;

    public int Length
    {

        get
        {
            return length;
        
        }
    }

    // .
}
    • 然而使用Length法進行字串判空串時,有一點要注意的,就是你必須先判斷該字串執行個體是否為空白引用,否則將會拋出NullReferenceException異常!於是,我們有了一個經過改進的Length法:

void Foo(string bar)
{
    if ((bar != null) && (bar.Length == 0))
        // 
}

3. 最後總結:

從上面的分析我們可以看到,使用Length法來進行字串判空串是有著很大的效能優勢的,尤其在進行大量字串判空時!當然首先得判斷字串執行個體是否為空白引用!

  1. 有關Reflector的介紹可以參見《Reflector: Get the secret inside .NET assemblies.》一文。
  2. 本代碼反編譯自版本號碼為2.0.3600.0的.NET Framework。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.