string.IsNullOrEmpty (string) vs. string.IsNullOrWhiteSpace (string)


207

Czy użycie string.IsNullOrEmpty(string)podczas sprawdzania łańcucha jest uważane za złą praktykę, gdy jest string.IsNullOrWhiteSpace(string)w .NET 4.0 i wyżej?

Odpowiedzi:


328

Najlepszą praktyką jest wybranie najbardziej odpowiedniej.

.Net Framework 4.0 Beta 2 ma nową metodę IsNullOrWhiteSpace () dla łańcuchów, która uogólnia metodę IsNullOrEmpty () tak, aby zawierała także inne białe znaki poza pustym ciągiem.

Termin „biała spacja” obejmuje wszystkie znaki, które nie są widoczne na ekranie. Na przykład spacja, podział wiersza, tabulator i pusty ciąg to białe znaki * .

Referencja: tutaj

Pod względem wydajności IsNullOrWhiteSpace nie jest idealny, ale jest dobry. Wywołania metod spowodują niewielki spadek wydajności. Ponadto sama metoda IsWhiteSpace ma pewne pośrednie elementy, które można usunąć, jeśli nie używasz danych Unicode. Jak zawsze przedwczesna optymalizacja może być zła, ale jest też zabawna.

Referencja: tutaj

Sprawdź kod źródłowy (Reference Source .NET Framework 4.6.2)

IsNullorEmpty

[Pure]
public static bool IsNullOrEmpty(String value) {
    return (value == null || value.Length == 0);
}

IsNullOrWhiteSpace

[Pure]
public static bool IsNullOrWhiteSpace(String value) {
    if (value == null) return true;

    for(int i = 0; i < value.Length; i++) {
        if(!Char.IsWhiteSpace(value[i])) return false;
    }

    return true;
}

Przykłady

string nullString = null;
string emptyString = "";
string whitespaceString = "    ";
string nonEmptyString = "abc123";

bool result;

result = String.IsNullOrEmpty(nullString);            // true
result = String.IsNullOrEmpty(emptyString);           // true
result = String.IsNullOrEmpty(whitespaceString);      // false
result = String.IsNullOrEmpty(nonEmptyString);        // false

result = String.IsNullOrWhiteSpace(nullString);       // true
result = String.IsNullOrWhiteSpace(emptyString);      // true
result = String.IsNullOrWhiteSpace(whitespaceString); // true
result = String.IsNullOrWhiteSpace(nonEmptyString);   // false

Teraz jestem zdezorientowany: „IsNullOrWhiteSpace to wygodna metoda podobna do następującego kodu, z tym wyjątkiem, że oferuje lepszą wydajność” tutaj: msdn.microsoft.com/en-us/library/…
robasta

@rob Kod return String.IsNullOrEmpty(value) || value.Trim().Length == 0;, o którym mowa, to nowy przydział ciągu i dwie osobne kontrole. Najprawdopodobniej wewnątrz IsNullOrWhitespace odbywa się to za pomocą pojedynczego przejścia bez żadnych przydziałów, sprawdzając, czy każdy znak w ciągu znaków jest białym znakiem, a tym samym lepszą wydajność. Co cię tak naprawdę myli?
Ivan Danilov

10
Dzięki! Nigdy nie wiedziałem, czy IsNullOrWhitespace()pasuje do pustej struny. W istocie IsNullOrEmpty()pasuje do podzbioru IsNullOrWhitespace().
gligoran

155

Różnice w praktyce:

string testString = "";
Console.WriteLine(string.Format("IsNullOrEmpty : {0}", string.IsNullOrEmpty(testString)));
Console.WriteLine(string.Format("IsNullOrWhiteSpace : {0}", string.IsNullOrWhiteSpace(testString)));
Console.ReadKey();

Result :
IsNullOrEmpty : True
IsNullOrWhiteSpace : True

**************************************************************
string testString = " MDS   ";

IsNullOrEmpty : False
IsNullOrWhiteSpace : False

**************************************************************
string testString = "   ";

IsNullOrEmpty : False
IsNullOrWhiteSpace : True

**************************************************************
string testString = string.Empty;

IsNullOrEmpty : True
IsNullOrWhiteSpace : True

**************************************************************
string testString = null;

IsNullOrEmpty : True
IsNullOrWhiteSpace : True

4
Moim zdaniem powinna to być zaakceptowana odpowiedź. Ma więcej sensu niż zaakceptowana odpowiedź, pokazując rzeczywiste przykłady zamiast przekierowania.
eaglei22

37

Są to różne funkcje. W swojej sytuacji powinieneś zdecydować, czego potrzebujesz.

Nie uważam używania żadnego z nich za złą praktykę. Większość czasu IsNullOrEmpty()wystarczy. Ale masz wybór :)


2
Na przykład pole nazwy użytkownika na stronie rejestracji używa IsNullOrEmtpy do sprawdzania poprawności, aby użytkownik nie mógł mieć spacji jako nazwy.
Chris

14
@Rfvgyhn: jeśli chcesz sprawdzić, czy w nazwie użytkownika nie ma nigdzie spacji - powinieneś użyć Contains. Jeśli chcesz się upewnić, że nazwa użytkownika nie może składać się tylko ze spacji - IsNullOrWhiteSpacejest w porządku. IsNullOrEmptyzapewnia, że ​​jakoś wprowadzono tylko nazwę użytkownika.
Ivan Danilov,

1
W rzeczy samej. Chciałem tylko podać konkretny przykład, który można dodać do twojej odpowiedzi. W prawdziwym świecie reguła sprawdzania poprawności nazwy użytkownika zwykle zawiera nieco więcej logiki niż tylko sprawdzanie, czy jest pusta czy biała.
Chris,

28

Oto faktyczna implementacja obu metod (dekompilowana za pomocą dotPeek)

[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    public static bool IsNullOrEmpty(string value)
    {
      if (value != null)
        return value.Length == 0;
      else
        return true;
    }

    /// <summary>
    /// Indicates whether a specified string is null, empty, or consists only of white-space characters.
    /// </summary>
    /// 
    /// <returns>
    /// true if the <paramref name="value"/> parameter is null or <see cref="F:System.String.Empty"/>, or if <paramref name="value"/> consists exclusively of white-space characters.
    /// </returns>
    /// <param name="value">The string to test.</param>
    public static bool IsNullOrWhiteSpace(string value)
    {
      if (value == null)
        return true;
      for (int index = 0; index < value.Length; ++index)
      {
        if (!char.IsWhiteSpace(value[index]))
          return false;
      }
      return true;
    }

4
To oznacza, że IsNullOrWhiteSpacedotyczy to string.Emptyrównież! To bonus :)
Ε Г И І И О

4
tak, najbezpieczniejszym będzie użycie IsNullOrWhiteSpace (True dla String.empty, null i spacja)
dekdev

7

Mówi, że to wszystko IsNullOrEmpty()nie obejmuje białych odstępów IsNullOrWhiteSpace()!

IsNullOrEmpty()Jeśli ciąg jest:
-Null
-Empty

IsNullOrWhiteSpace()Jeśli ciąg jest:
-Null
-Empty -Contains Tylko
białe spacje


2
Odrzuciłem głos, ponieważ wyjaśniając, co robi każda funkcja, nie odpowiadasz na rzeczywiste pytanie.
tuespetre

2
Powinieneś edytować swoją odpowiedź, aby uwzględnić całą listę „białych znaków”, zgodnie z definicją frameworka: Termin „białe znaki” obejmuje wszystkie znaki, które nie są widoczne na ekranie. Na przykład spacja, podział wiersza, tabulator i pusty ciąg znaków to białe znaki.
georger

2

Sprawdź to za pomocą IsNullOrEmpty i IsNullOrwhiteSpace

string sTestes = "I like sweat peaches";
    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();
    for (int i = 0; i < 5000000; i++)
    {
        for (int z = 0; z < 500; z++)
        {
            var x = string.IsNullOrEmpty(sTestes);// OR string.IsNullOrWhiteSpace
        }
    }

    stopWatch.Stop();
    // Get the elapsed time as a TimeSpan value.
    TimeSpan ts = stopWatch.Elapsed;
    // Format and display the TimeSpan value. 
    string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
        ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
    Console.WriteLine("RunTime " + elapsedTime);
    Console.ReadLine();

Przekonasz się, że IsNullOrWhiteSpace jest znacznie wolniejszy: /


1
Jest to oczywiste, ponieważ IsNullOrEmpty dzieje się w stałym czasie O (1), podczas gdy IsNullOrwhiteSpace prawdopodobnie wymaga pełnej iteracji ciągu lub czasu O (n). W takim przypadku twój przykładowy czas faktycznie używa prawie O (n ^ 2) czasu. W przypadku zegara jednorazowego z łańcuchem o normalnym rozmiarze różnica wydajności będzie nieznaczna. Jeśli przetwarzałeś bardzo duże ilości tekstu lub wywoływałeś go w dużej pętli, prawdopodobnie nie chciałbyś go używać.
Charles Owen

1

string.IsNullOrEmpty (str) - jeśli chcesz sprawdzić, czy podano wartość ciągu

string.IsNullOrWhiteSpace (str) - zasadniczo jest to już rodzaj implementacji logiki biznesowej (tj. dlaczego „” jest zły, ale coś takiego jak „~~” jest dobre).

Moja rada - nie łącz logiki biznesowej z kontrolami technicznymi. Na przykład string.IsNullOrEmpty najlepiej stosować na początku metod do sprawdzania parametrów wejściowych.


0

Co powiesz na połów wszystkich ...

if (string.IsNullOrEmpty(x.Trim())
{
}

Spowoduje to przycięcie wszystkich spacji, jeśli są, unikając ujemnego wpływu na wydajność IsWhiteSpace, co umożliwi łańcuchowi spełnienie warunku „pustego”, jeśli nie jest on zerowy.

Sądzę również, że jest to bardziej zrozumiałe i ogólnie jest dobrą praktyką przycinanie ciągów, szczególnie jeśli umieszczasz je w bazie danych lub coś takiego.


34
Ta kontrola ma poważną wadę. Wywołanie Trim () na x spowoduje wyjątek odwołania zerowego, gdy zostanie przekazany jako null.
Г Г И І И О

9
Słuszna uwaga. Pozostawię niepoprawną odpowiedź, aby pokazać wadę.
Remotec,

1
IsNullOrWhitespace MOŻE zoptymalizować, aby sprawdzić, czy jest pusta lub pusta, unikając sprawdzania ciągu pod kątem spacji. Ta metoda zawsze wykonuje operację przycinania. Ponadto, choć można go zoptymalizować, prawdopodobnie utworzy kolejny ciąg w pamięci.
Sprague,

if (string.IsNullOrEmpty (x? .Trim ()) powinien obejść problem zerowy
Cameron Forward

0

W .Net standard 2.0:

string.IsNullOrEmpty(): Wskazuje, czy określony ciąg jest pusty lub pusty.

Console.WriteLine(string.IsNullOrEmpty(null));           // True
Console.WriteLine(string.IsNullOrEmpty(""));             // True
Console.WriteLine(string.IsNullOrEmpty(" "));            // False
Console.WriteLine(string.IsNullOrEmpty("  "));           // False

string.IsNullOrWhiteSpace(): Wskazuje, czy określony ciąg jest pusty, czy zawiera tylko znaki spacji.

Console.WriteLine(string.IsNullOrWhiteSpace(null));     // True
Console.WriteLine(string.IsNullOrWhiteSpace(""));       // True
Console.WriteLine(string.IsNullOrWhiteSpace(" "));      // True
Console.WriteLine(string.IsNullOrWhiteSpace("  "));     // True
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.