1. 程式人生 > >C# 關於判斷字串為空的一些方法

C# 關於判斷字串為空的一些方法

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](片段):

publicsealedclass String : IComparable, ICloneable, IConvertible, IEnumerable, IComparable<string>
{
    
static String()
    
{
        
string.Empty ="";

        
// Code here
    }


    
// Code here

    
publicstaticreadonlystring Empty;

    
publicstaticbooloperator
==(string a, string b)
    
{
        
returnstring.Equals(a, b);
    }


    
publicstaticbool Equals(string a, string b)
    
{
        
if (a == b)
        
{
            
returntrue;
        }

        
if ((a !=null&& (b !=null))
        
{
            
returnstring.EqualsHelper(a, b);
        }

        
returnfalse;
    }


    
privatestaticunsafebool EqualsHelper(string ao, string bo)
    
{
        
// Code here

        
int num1 = ao.Length;
        
if (num1 != bo.Length)
        
{
            
returnfalse;
        }

       
        
// Code here
    }


    
privateexternint InternalLength();

    
publicint Length
    
{
        
get
        
{
            
returnthis.InternalLength();
        }

    }


    
// Code here
}


Rotor裡面String類的程式碼與此沒什麼不同,只是沒有EqualsHelper方法,代之以如下的宣告:

publicexternbool Equals(String value);

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

publicstaticbooloperator==(string a, string b);

publicstaticbool Equals(string a, string b);

privatestaticunsafebool EqualsHelper(string ao, string bo);

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

class String
{
    
privateint length;

    
publicint Length
    
{

        
get
        
{
            
return length;
       
        }

    }


    
// .
}


然而使用Length法進行字串判空串時,有一點要注意的,就是你必須先判斷該字串例項是否為空引用,否則將會丟擲NullReferenceException異常!於是,我們有了一個經過改進的Length法:

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


3. 最後總結:
從上面的分析我們可以看到,使用Length法來進行字串判空串是有著很大的效能優勢的,尤其在進行大量字串判空時!當然首先得判斷字串例項是否為空引用!