Najlepsze rozwiązania dotyczące używania ciągów w programie .NETBest Practices for Using Strings in .NET

Platforma .NET zapewnia rozbudowaną obsługę tworzenia zlokalizowanych i globalnych aplikacji oraz ułatwia stosowanie Konwencji dla bieżącej kultury lub określonej kultury podczas wykonywania typowych operacji, takich jak sortowanie i wyświetlanie ciągów..NET provides extensive support for developing localized and globalized applications, and makes it easy to apply the conventions of either the current culture or a specific culture when performing common operations such as sorting and displaying strings. Jednak sortowanie lub Porównywanie ciągów nie zawsze jest operacją zależną od kultury.But sorting or comparing strings is not always a culture-sensitive operation. Na przykład ciągi, które są używane wewnętrznie przez aplikację zwykle, powinny być obsługiwane identycznie we wszystkich kulturach.For example, strings that are used internally by an application typically should be handled identically across all cultures. Gdy dane niezależne od kultury, takie jak tagi XML, Tagi HTML, nazwy użytkowników, ścieżki plików i nazwy obiektów systemowych, są interpretowane tak, jakby były wrażliwe na kulturę, kod aplikacji może podlegać rozdrobnym usterkom, złej wydajności i, w niektórych przypadkach, Problemy z zabezpieczeniami.When culturally independent string data, such as XML tags, HTML tags, user names, file paths, and the names of system objects, are interpreted as if they were culture-sensitive, application code can be subject to subtle bugs, poor performance, and, in some cases, security issues.

W tym temacie opisano metody sortowania, porównywania i wielkości liter w programie .NET, przedstawiono zalecenia dotyczące wybierania odpowiedniej metody obsługi ciągów i zawiera dodatkowe informacje na temat metod obsługi ciągów.This topic examines the string sorting, comparison, and casing methods in .NET, presents recommendations for selecting an appropriate string-handling method, and provides additional information about string-handling methods. Bada także, jak sformatowane dane, takie jak dane liczbowe oraz dane daty i godziny, są obsługiwane na potrzeby wyświetlania i przechowywania.It also examines how formatted data, such as numeric data and date and time data, is handled for display and for storage.

Ten temat zawiera następujące sekcje:This topic contains the following sections:

Zalecenia dotyczące korzystania z ciągówRecommendations for String Usage

Podczas opracowywania przy użyciu platformy .NET należy przestrzegać następujących prostych zaleceń w przypadku używania ciągów:When you develop with .NET, follow these simple recommendations when you use strings:

W przypadku używania ciągów należy unikać następujących praktyk:Avoid the following practices when you use strings:

  • Nie należy używać przeciążeń, które nie jawnie lub niejawnie określają reguły porównywania ciągów dla operacji na ciągach.Do not use overloads that do not explicitly or implicitly specify the string comparison rules for string operations.

  • Nie używaj StringComparison.InvariantCulture w większości przypadków operacji na ciągach.Do not use string operations based on StringComparison.InvariantCulture in most cases. Jednym z kilku wyjątków jest to, że w przypadku utrwalania w sposób istotny, ale kulturalnie niezależny od dane.One of the few exceptions is when you are persisting linguistically meaningful but culturally agnostic data.

  • Nie należy używać przeciążenia String.Compare metody lub CompareTo i testu dla zwracanej wartości zero, aby określić, czy dwa ciągi są równe.Do not use an overload of the String.Compare or CompareTo method and test for a return value of zero to determine whether two strings are equal.

  • Nie używaj formatowania z uwzględnieniem kultury, aby zachować dane liczbowe lub dane daty i godziny w postaci ciągu.Do not use culture-sensitive formatting to persist numeric data or date and time data in string form.

Powrót do początkuBack to top

Jawne określenie porównywania ciągówSpecifying String Comparisons Explicitly

Większość metod manipulowania ciągami w .NET jest przeciążona.Most of the string manipulation methods in .NET are overloaded. Zazwyczaj co najmniej jedno Przeciążenie przyjmuje ustawienia domyślne, natomiast inne nie akceptują żadnych ustawień domyślnych, a zamiast tego definiują precyzyjne metody porównywania ciągów lub manipulowania nimi.Typically, one or more overloads accept default settings, whereas others accept no defaults and instead define the precise way in which strings are to be compared or manipulated. Większość metod, które nie bazują na wartościach domyślnych, zawiera parametr typu StringComparison, który jest wyliczeniem, które jawnie określa reguły dla porównania ciągów przez kulturę i wielkość liter.Most of the methods that do not rely on defaults include a parameter of type StringComparison, which is an enumeration that explicitly specifies rules for string comparison by culture and case. W poniższej tabeli opisano StringComparison elementy członkowskie wyliczenia.The following table describes the StringComparison enumeration members.

StringComparison element członkowskiStringComparison member OpisDescription
CurrentCulture Wykonuje porównanie z rozróżnianiem wielkości liter przy użyciu bieżącej kultury.Performs a case-sensitive comparison using the current culture.
CurrentCultureIgnoreCase Wykonuje porównanie bez uwzględniania wielkości liter przy użyciu bieżącej kultury.Performs a case-insensitive comparison using the current culture.
InvariantCulture Wykonuje porównanie z rozróżnianiem wielkości liter przy użyciu niezmiennej kultury.Performs a case-sensitive comparison using the invariant culture.
InvariantCultureIgnoreCase Wykonuje porównanie bez uwzględniania wielkości liter przy użyciu niezmiennej kultury.Performs a case-insensitive comparison using the invariant culture.
Ordinal Wykonuje porównanie porządkowe.Performs an ordinal comparison.
OrdinalIgnoreCase Wykonuje porównanie porządkowe bez uwzględniania wielkości liter.Performs a case-insensitive ordinal comparison.

Na przykład IndexOf Metoda, która zwraca indeks podciągu String w obiekcie, który pasuje do znaku lub ciągu, ma dziewięć przeciążeń:For example, the IndexOf method, which returns the index of a substring in a String object that matches either a character or a string, has nine overloads:

Zalecamy wybranie przeciążenia, które nie używa wartości domyślnych, z następujących powodów:We recommend that you select an overload that does not use default values, for the following reasons:

  • Niektóre przeciążenia z domyślnymi parametrami (te, które Char wyszukują w wystąpieniu ciągu) wykonują porównanie porządkowe, natomiast inne (te, które wyszukują ciąg w wystąpieniu ciągu) są zależne od kultury.Some overloads with default parameters (those that search for a Char in the string instance) perform an ordinal comparison, whereas others (those that search for a string in the string instance) are culture-sensitive. Trudno jest pamiętać, która metoda używa tej wartości domyślnej i łatwej do odróżnienia przeciążenia.It is difficult to remember which method uses which default value, and easy to confuse the overloads.

  • Zamiar kodu, który opiera się na wartościach domyślnych dla wywołań metod, nie jest jasne.The intent of the code that relies on default values for method calls is not clear. W poniższym przykładzie, który opiera się na wartościach domyślnych, trudno jest wiedzieć, czy deweloper rzeczywiście zaproponował numer porządkowy, czy też jest porównywany z dwoma ciągami, czy protocol też różnica wielkości liter między i "http" może spowodować równość testów do zwrócenia false.In the following example, which relies on defaults, it is difficult to know whether the developer actually intended an ordinal or a linguistic comparison of two strings, or whether a case difference between protocol and "http" might cause the test for equality to return false.

    string protocol = GetProtocol(url);       
    if (String.Equals(protocol, "http")) {
       // ...Code to handle HTTP protocol.
    }
    else {
       throw new InvalidOperationException();
    }
    
    Dim protocol As String = GetProtocol(url)       
    If String.Equals(protocol, "http") Then
       ' ...Code to handle HTTP protocol.
    Else
       Throw New InvalidOperationException()
    End If   
    

Ogólnie rzecz biorąc zalecamy wywołanie metody, która nie polega na wartościach domyślnych, ponieważ sprawia, że zamiar kodu jest niejednoznaczny.In general, we recommend that you call a method that does not rely on defaults, because it makes the intent of the code unambiguous. Dzięki temu kod staje się bardziej czytelny i łatwiejszy w debugowaniu i obsłudze.This, in turn, makes the code more readable and easier to debug and maintain. Poniższy przykład dotyczy odpowiedzi na pytania dotyczące poprzedniego przykładu.The following example addresses the questions raised about the previous example. Sprawia, że jest ono jasne, że jest używane porównanie porządkowe oraz że różnice w przypadku są ignorowane.It makes it clear that ordinal comparison is used and that differences in case are ignored.

string protocol = GetProtocol(url);       
if (String.Equals(protocol, "http", StringComparison.OrdinalIgnoreCase)) {
   // ...Code to handle HTTP protocol.
}
else {
   throw new InvalidOperationException();
}
Dim protocol As String = GetProtocol(url)       
If String.Equals(protocol, "http", StringComparison.OrdinalIgnoreCase) Then
   ' ...Code to handle HTTP protocol.
Else
   Throw New InvalidOperationException()
End If   

Powrót do początkuBack to top

Szczegóły dotyczące porównania ciągówThe Details of String Comparison

Porównanie ciągów jest sercem wielu operacji związanych z ciągami, szczególnie sortowania i testowania pod kątem równości.String comparison is the heart of many string-related operations, particularly sorting and testing for equality. Ciągi są sortowane w określonej kolejności: Jeśli "my" pojawia się przed "String" w posortowanej liście ciągów, "my" musi być porównywany z "ciągiem" lub "w".Strings sort in a determined order: If "my" appears before "string" in a sorted list of strings, "my" must compare less than or equal to "string". Ponadto porównanie niejawnie definiuje równość.Additionally, comparison implicitly defines equality. Operacja porównywania zwraca wartość zero dla ciągów, które uzna za równe.The comparison operation returns zero for strings it deems equal. Dobrą interpretacją jest to, że żaden ciąg nie jest mniejszy od drugiego.A good interpretation is that neither string is less than the other. Większość znaczących operacji obejmujących ciągi zawierają jedną lub obie te procedury: porównanie z innym ciągiem i wykonywanie dobrze zdefiniowanej operacji sortowania.Most meaningful operations involving strings include one or both of these procedures: comparing with another string, and executing a well-defined sort operation.

Uwaga

Można pobrać tabele wagi sortowania, zestaw plików tekstowych, które zawierają informacje o wagach znaków używanych w operacjach sortowania i porównywania dla systemów operacyjnych Windows, a także domyślną tabelę elementów sortowania Unicode, Najnowsza wersja tabeli Sortuj wagi dla systemów Linux i macOS.You can download the Sorting Weight Tables, a set of text files that contain information on the character weights used in sorting and comparison operations for Windows operating systems, and the Default Unicode Collation Element Table, the latest version of the sort weight table for Linux and macOS. Określona wersja tabeli posortowanych wag w systemie Linux i macOS zależy od wersji międzynarodowych składników dla bibliotek Unicode zainstalowanych w systemie.The specific version of the sort weight table on Linux and macOS depends on the version of the International Components for Unicode libraries installed on the system. Aby uzyskać informacje na temat wersji ICU i wersji standardu Unicode, które implementują, zobacz pobieranie ICU.For information on ICU versions and the Unicode versions that they implement, see Downloading ICU.

Jednak Ocena dwóch ciągów dla równości lub kolejności sortowania nie daje pojedynczego prawidłowego wyniku; wyniki są zależne od kryteriów używanych do porównywania ciągów.However, evaluating two strings for equality or sort order does not yield a single, correct result; the outcome depends on the criteria used to compare the strings. W szczególności porównania ciągów, które są numerami porządkowymi lub które są oparte na konwencjach wielkości liter i sortowania bieżącej kultury lub niezmiennej kultury (niezależny od kultury opartej na języku angielskim) mogą generować różne wyniki.In particular, string comparisons that are ordinal or that are based on the casing and sorting conventions of the current culture or the invariant culture (a locale-agnostic culture based on the English language) may produce different results.

Ponadto porównania ciągów przy użyciu różnych wersji programu .NET lub programu .NET w różnych systemach operacyjnych lub wersjach systemu operacyjnego mogą zwracać różne wyniki.In addition, string comparisons using different versions of .NET or using .NET on different operating systems or operating system versions may return different results. Aby uzyskać więcej informacji, zobacz ciągi i standard Unicode.For more information, see Strings and the Unicode Standard.

Porównywanie ciągów, które używają bieżącej kulturyString Comparisons that Use the Current Culture

Jedno kryterium obejmuje stosowanie Konwencji bieżącej kultury podczas porównywania ciągów.One criterion involves using the conventions of the current culture when comparing strings. Porównania, które są oparte na bieżącej kulturze, wykorzystują bieżącą kulturę lub ustawienia regionalne wątku.Comparisons that are based on the current culture use the thread's current culture or locale. Jeśli kultura nie jest ustawiona przez użytkownika, domyślnie jest to ustawienie w oknie Opcje regionalne w panelu sterowania.If the culture is not set by the user, it defaults to the setting in the Regional Options window in Control Panel. Należy zawsze używać porównań, które są oparte na bieżącej kulturze, gdy dane są istotne dla kultury, a kiedy odzwierciedlają interakcję z użytkownikiem uwzględniającą kulturę.You should always use comparisons that are based on the current culture when data is linguistically relevant, and when it reflects culture-sensitive user interaction.

Jednak porównanie i wielkość liter w programie .NET zmieniają się po zmianie kultury.However, comparison and casing behavior in .NET changes when the culture changes. Dzieje się tak, gdy aplikacja jest wykonywana na komputerze z inną kulturą niż komputer, na którym aplikacja została opracowana, lub gdy wątek wykonawczy zmienia jego kulturę.This happens when an application executes on a computer that has a different culture than the computer on which the application was developed, or when the executing thread changes its culture. To zachowanie jest zamierzone, ale pozostaje nieoczywista dla wielu deweloperów.This behavior is intentional, but it remains non-obvious to many developers. Poniższy przykład ilustruje różnice w kolejności sortowania między Stanami USA Angielskie ("en-US") i szwedzki ("SV-SE").The following example illustrates differences in sort order between the U.S. English ("en-US") and Swedish ("sv-SE") cultures. Zwróć uwagę, że słowa "Ångström", "Windows" i "Visual Studio" pojawiają się w różnych pozycjach w posortowanych tablicach ciągów.Note that the words "ångström", "Windows", and "Visual Studio" appear in different positions in the sorted string arrays.

using System;
using System.Globalization;
using System.Threading;

public class Example
{
   public static void Main()
   {
      string[] values= { "able", "ångström", "apple", "Æble", 
                         "Windows", "Visual Studio" };
      Array.Sort(values);
      DisplayArray(values);

      // Change culture to Swedish (Sweden).
      string originalCulture = CultureInfo.CurrentCulture.Name;
      Thread.CurrentThread.CurrentCulture = new CultureInfo("sv-SE");
      Array.Sort(values);
      DisplayArray(values);

      // Restore the original culture.
      Thread.CurrentThread.CurrentCulture = new CultureInfo(originalCulture);
    }
    
    private static void DisplayArray(string[] values)
    {
      Console.WriteLine("Sorting using the {0} culture:",  
                        CultureInfo.CurrentCulture.Name);
      foreach (string value in values)
         Console.WriteLine("   {0}", value);

      Console.WriteLine();
    }
}
// The example displays the following output:
//       Sorting using the en-US culture:
//          able
//          Æble
//          ångström
//          apple
//          Visual Studio
//          Windows
//       
//       Sorting using the sv-SE culture:
//          able
//          Æble
//          apple
//          Windows
//          Visual Studio
//          ångström
Imports System.Globalization
Imports System.Threading

Module Example
   Public Sub Main()
      Dim values() As String = { "able", "ångström", "apple", _
                                 "Æble", "Windows", "Visual Studio" }
      Array.Sort(values)
      DisplayArray(values)

      ' Change culture to Swedish (Sweden).
      Dim originalCulture As String = CultureInfo.CurrentCulture.Name
      Thread.CurrentThread.CurrentCulture = New CultureInfo("sv-SE")
      Array.Sort(values)
      DisplayArray(values)

      ' Restore the original culture.
      Thread.CurrentThread.CurrentCulture = New CultureInfo(originalCulture)
    End Sub
    
    Private Sub DisplayArray(values() As String)
      Console.WRiteLine("Sorting using the {0} culture:", _ 
                        CultureInfo.CurrentCulture.Name)
      For Each value As String In values
         Console.WriteLine("   {0}", value)
      Next
      Console.WriteLine()   
    End Sub
End Module
' The example displays the following output:
'       Sorting using the en-US culture:
'          able
'          Æble
'          ångström
'          apple
'          Visual Studio
'          Windows
'       
'       Sorting using the sv-SE culture:
'          able
'          Æble
'          apple
'          Windows
'          Visual Studio
'          ångström

Porównania bez uwzględniania wielkości liter, które używają bieżącej kultury, są takie same jak porównania uwzględniające kulturę, z tą różnicą, że ignorowanie wielkości liter jako podyktowanych przez bieżącą kulturę wątku.Case-insensitive comparisons that use the current culture are the same as culture-sensitive comparisons, except that they ignore case as dictated by the thread's current culture. Takie zachowanie może być również w porządku sortowania.This behavior may manifest itself in sort orders as well.

Porównania, które używają bieżącej semantyki kultury, są domyślne dla następujących metod:Comparisons that use current culture semantics are the default for the following methods:

W każdym przypadku zalecamy wywołanie przeciążenia, które ma StringComparison parametr, aby przeznaczenie metody zostało wyczyszczone.In any case, we recommend that you call an overload that has a StringComparison parameter to make the intent of the method call clear.

Subtelne i nietak rozdrobne usterki mogą naciągać się, gdy dane nielingwistyczne nie są interpretowane językowo lub gdy dane ciągów z określonej kultury są interpretowane przy użyciu konwencji innej kultury.Subtle and not so subtle bugs can emerge when non-linguistic string data is interpreted linguistically, or when string data from a particular culture is interpreted using the conventions of another culture. Przykładem kanonicznym jest problem z tureckim I.The canonical example is the Turkish-I problem.

Dla niemal wszystkich alfabetów łacińskich, w tym dla Stanów Zjednoczonych Angielski, znak "i" (\u0069) to mała wersja znaku "I" (\u0049).For nearly all Latin alphabets, including U.S. English, the character "i" (\u0069) is the lowercase version of the character "I" (\u0049). Ta reguła wielkości liter jest szybko zmieniana na wartość domyślną dla programowania osób w takiej kulturze.This casing rule quickly becomes the default for someone programming in such a culture. Alfabet turecki ("TR-TR") zawiera jednak znak "i" (\u0130), czyli "i" w Wielkiej wersji "i".However, the Turkish ("tr-TR") alphabet includes an "I with a dot" character "İ" (\u0130), which is the capital version of "i". Turecki zawiera również małe litery "i bez kropki", "ı" (\u0131), które zaczynają się od litery "I".Turkish also includes a lowercase "i without a dot" character, "ı" (\u0131), which capitalizes to "I". To zachowanie występuje również w kulturze azerski ("AZ").This behavior occurs in the Azerbaijani ("az") culture as well.

W związku z tym, założenia dotyczące Wielkiej litery "i" lub "lowercasing" nie są prawidłowe we wszystkich kulturach.Therefore, assumptions made about capitalizing "i" or lowercasing "I" are not valid among all cultures. Jeśli użyjesz domyślnych przeciążeń dla procedur porównywania ciągów, będą one podlegać wariancji między kulturami.If you use the default overloads for string comparison routines, they will be subject to variance between cultures. Jeśli dane, które mają być porównane, nie są językowe, użycie domyślnych przeciążeń może dawać niepożądane wyniki, ponieważ poniżej podjęto próbę wykonania porównania ciągów "File" i "FILE" bez uwzględniania wielkości liter.If the data to be compared is non-linguistic, using the default overloads can produce undesirable results, as the following attempt to perform a case-insensitive comparison of the strings "file" and "FILE" illustrates.

using System;
using System.Globalization;
using System.Threading;

public class Example
{
   public static void Main()
   {
      string fileUrl = "file";
      Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
      Console.WriteLine("Culture = {0}",
                        Thread.CurrentThread.CurrentCulture.DisplayName);
      Console.WriteLine("(file == FILE) = {0}", 
                       fileUrl.StartsWith("FILE", true, null));
      Console.WriteLine();
      
      Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");
      Console.WriteLine("Culture = {0}",
                        Thread.CurrentThread.CurrentCulture.DisplayName);
      Console.WriteLine("(file == FILE) = {0}", 
                        fileUrl.StartsWith("FILE", true, null));
   }
}
// The example displays the following output:
//       Culture = English (United States)
//       (file == FILE) = True
//       
//       Culture = Turkish (Turkey)
//       (file == FILE) = False
Imports System.Globalization
Imports System.Threading

Module Example
   Public Sub Main()
      Dim fileUrl = "file"
      Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
      Console.WriteLine("Culture = {0}", _
                        Thread.CurrentThread.CurrentCulture.DisplayName)
      Console.WriteLine("(file == FILE) = {0}", _ 
                       fileUrl.StartsWith("FILE", True, Nothing))
      Console.WriteLine()
      
      Thread.CurrentThread.CurrentCulture = New CultureInfo("tr-TR")
      Console.WriteLine("Culture = {0}", _
                        Thread.CurrentThread.CurrentCulture.DisplayName)
      Console.WriteLine("(file == FILE) = {0}", _ 
                        fileUrl.StartsWith("FILE", True, Nothing))
   End Sub
End Module
' The example displays the following output:
'       Culture = English (United States)
'       (file == FILE) = True
'       
'       Culture = Turkish (Turkey)
'       (file == FILE) = False

To porównanie może spowodować znaczne problemy, jeśli kultura jest przypadkowo używana w ustawieniach zabezpieczeń, jak w poniższym przykładzie.This comparison could cause significant problems if the culture is inadvertently used in security-sensitive settings, as in the following example. Wywołanie metody, takie jak IsFileURI("file:") Returns true , jeśli bieżąca kultura jest w Stanach Zjednoczonych Angielski, ale false Jeśli bieżąca kultura to turecki.A method call such as IsFileURI("file:") returns true if the current culture is U.S. English, but false if the current culture is Turkish. W takim przypadku, w systemach tureckich, ktoś może obejść środki bezpieczeństwa, które blokują dostęp do identyfikatorów URI bez uwzględniania wielkości liter zaczynających się od "FILE:".Thus, on Turkish systems, someone could circumvent security measures that block access to case-insensitive URIs that begin with "FILE:".

public static bool IsFileURI(String path) 
{
   return path.StartsWith("FILE:", true, null);
}
Public Shared Function IsFileURI(path As String) As Boolean 
   Return path.StartsWith("FILE:", True, Nothing)
End Function

W tym przypadku, ponieważ "plik:" ma być interpretowany jako niezależny od języka, kod powinien być zapisany, jak pokazano w poniższym przykładzie.In this case, because "file:" is meant to be interpreted as a non-linguistic, culture-insensitive identifier, the code should instead be written as shown in the following example.

public static bool IsFileURI(string path) 
{
   return path.StartsWith("FILE:", StringComparison.OrdinalIgnoreCase);
}
Public Shared Function IsFileURI(path As String) As Boolean 
    Return path.StartsWith("FILE:", StringComparison.OrdinalIgnoreCase)
End Function

Operacje na ciągach porządkowychOrdinal String Operations

Określenie wartości StringComparison.OrdinalIgnoreCase lub w wywołaniu metody oznacza, że jest to porównanie w języku innym niż język, w którym funkcje języków naturalnych są ignorowane. StringComparison.OrdinalSpecifying the StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase value in a method call signifies a non-linguistic comparison in which the features of natural languages are ignored. Metody, które są wywoływane z StringComparison tymi wartościami, podejmuje decyzje dotyczące operacji na ciągach prostych w przypadku porównywania bajtów zamiast wielkości liter lub tabel równoważności, które są sparametryzowane przez kulturę.Methods that are invoked with these StringComparison values base string operation decisions on simple byte comparisons instead of casing or equivalence tables that are parameterized by culture. W większości przypadków takie podejście najlepiej pasuje do zamierzonej interpretacji ciągów podczas szybszego wykonywania kodu i bardziej niezawodnego.In most cases, this approach best fits the intended interpretation of strings while making code faster and more reliable.

Porównania porządkowe to porównania ciągów, w których każdy bajt każdego ciągu jest porównywany bez interpretacji językowej; na przykład "Windows" nie pasuje do "Windows".Ordinal comparisons are string comparisons in which each byte of each string is compared without linguistic interpretation; for example, "windows" does not match "Windows". Jest to zasadniczo wywołanie funkcji środowiska uruchomieniowego strcmp języka C.This is essentially a call to the C runtime strcmp function. Użyj tego porównania, gdy kontekst określa, że ciągi powinny być dokładnie dopasowane lub wymagające ostrożnej zgodności z zasadami.Use this comparison when the context dictates that strings should be matched exactly or demands conservative matching policy. Ponadto, porównanie porządkowe jest najszybszą operacją porównywania, ponieważ nie stosuje żadnych reguł lingwistycznych podczas określania wyniku.Additionally, ordinal comparison is the fastest comparison operation because it applies no linguistic rules when determining a result.

Ciągi w programie .NET mogą zawierać osadzone znaki o wartości null.Strings in .NET can contain embedded null characters. Jedną z najwyraźniejszych różnic między porównaniem porządkowym i kulturowym (w tym porównaniami korzystającymi z niezmiennej kultury) jest obsługa osadzonych znaków null w ciągu.One of the clearest differences between ordinal and culture-sensitive comparison (including comparisons that use the invariant culture) concerns the handling of embedded null characters in a string. Te znaki są ignorowane w przypadku używania String.Compare metod i do wykonywania porównań z uwzględnieniem kultury (w String.Equals tym porównań, które używają niezmiennej kultury).These characters are ignored when you use the String.Compare and String.Equals methods to perform culture-sensitive comparisons (including comparisons that use the invariant culture). W związku z tym w porównaniach wrażliwych na kulturę ciągi zawierające osadzone znaki null mogą być traktowane jako równe ciągom, które nie.As a result, in culture-sensitive comparisons, strings that contain embedded null characters can be considered equal to strings that do not.

Ważne

Chociaż metody porównywania ciągów zignorują osadzone znaki null, metody wyszukiwania ciągów String.Contains, String.EndsWithtakie String.IndexOfjak String.LastIndexOf,, String.StartsWith ,, i nie.Although string comparison methods disregard embedded null characters, string search methods such as String.Contains, String.EndsWith, String.IndexOf, String.LastIndexOf, and String.StartsWith do not.

Poniższy przykład wykonuje porównanie z uwzględnieniem kultury ciągu "AA" z podobnym ciągiem, który zawiera kilka osadzonych znaków o wartości null między "A" i "a" i pokazuje, jak dwa ciągi są uważane za równe.The following example performs a culture-sensitive comparison of the string "Aa" with a similar string that contains several embedded null characters between "A" and "a", and shows how the two strings are considered equal.

using System;

public class Example
{
   public static void Main()
   {
      string str1 = "Aa";
      string str2 = "A" + new String('\u0000', 3) + "a";
      Console.WriteLine("Comparing '{0}' ({1}) and '{2}' ({3}):", 
                        str1, ShowBytes(str1), str2, ShowBytes(str2));
      Console.WriteLine("   With String.Compare:");
      Console.WriteLine("      Current Culture: {0}", 
                        String.Compare(str1, str2, StringComparison.CurrentCulture));
      Console.WriteLine("      Invariant Culture: {0}", 
                        String.Compare(str1, str2, StringComparison.InvariantCulture));

      Console.WriteLine("   With String.Equals:");
      Console.WriteLine("      Current Culture: {0}", 
                        String.Equals(str1, str2, StringComparison.CurrentCulture));
      Console.WriteLine("      Invariant Culture: {0}", 
                        String.Equals(str1, str2, StringComparison.InvariantCulture));
   }
   
   private static string ShowBytes(string str)
   {
      string hexString = String.Empty;
      for (int ctr = 0; ctr < str.Length; ctr++)
      {
         string result = String.Empty;
         result = Convert.ToInt32(str[ctr]).ToString("X4");
         result = " " + result.Substring(0,2) + " " + result.Substring(2, 2);
         hexString += result;
      }
      return hexString.Trim();
   }
}
// The example displays the following output:
//    Comparing 'Aa' (00 41 00 61) and 'A   a' (00 41 00 00 00 00 00 00 00 61):
//       With String.Compare:
//          Current Culture: 0
//          Invariant Culture: 0
//       With String.Equals:
//          Current Culture: True
//          Invariant Culture: True
Module Example
   Public Sub Main()
      Dim str1 As String = "Aa"
      Dim str2 As String = "A" + New String(Convert.ToChar(0), 3) + "a"
      Console.WriteLine("Comparing '{0}' ({1}) and '{2}' ({3}):", _
                        str1, ShowBytes(str1), str2, ShowBytes(str2))
      Console.WriteLine("   With String.Compare:")
      Console.WriteLine("      Current Culture: {0}", _
                        String.Compare(str1, str2, StringComparison.CurrentCulture))
      Console.WriteLine("      Invariant Culture: {0}", _
                        String.Compare(str1, str2, StringComparison.InvariantCulture))

      Console.WriteLine("   With String.Equals:")
      Console.WriteLine("      Current Culture: {0}", _
                        String.Equals(str1, str2, StringComparison.CurrentCulture))
      Console.WriteLine("      Invariant Culture: {0}", _
                        String.Equals(str1, str2, StringComparison.InvariantCulture))
   End Sub
   
   Private Function ShowBytes(str As String) As String
      Dim hexString As String = String.Empty
      For ctr As Integer = 0 To str.Length - 1
         Dim result As String = String.Empty
         result = Convert.ToInt32(str.Chars(ctr)).ToString("X4")
         result = " " + result.Substring(0,2) + " " + result.Substring(2, 2)
         hexString += result
      Next
      Return hexString.Trim()
   End Function
End Module

Jednak ciągi nie są uważane za równe w przypadku używania porównania porządkowego, jak pokazano w poniższym przykładzie.However, the strings are not considered equal when you use ordinal comparison, as the following example shows.

Console.WriteLine("Comparing '{0}' ({1}) and '{2}' ({3}):", 
                  str1, ShowBytes(str1), str2, ShowBytes(str2));
Console.WriteLine("   With String.Compare:");
Console.WriteLine("      Ordinal: {0}", 
                  String.Compare(str1, str2, StringComparison.Ordinal));

Console.WriteLine("   With String.Equals:");
Console.WriteLine("      Ordinal: {0}", 
                  String.Equals(str1, str2, StringComparison.Ordinal));
// The example displays the following output:
//    Comparing 'Aa' (00 41 00 61) and 'A   a' (00 41 00 00 00 00 00 00 00 61):
//       With String.Compare:
//          Ordinal: 97
//       With String.Equals:
//          Ordinal: False
Console.WriteLine("Comparing '{0}' ({1}) and '{2}' ({3}):", _
                  str1, ShowBytes(str1), str2, ShowBytes(str2))
Console.WriteLine("   With String.Compare:")
Console.WriteLine("      Ordinal: {0}", _
                  String.Compare(str1, str2, StringComparison.Ordinal))

Console.WriteLine("   With String.Equals:")
Console.WriteLine("      Ordinal: {0}", _
                  String.Equals(str1, str2, StringComparison.Ordinal))
' The example displays the following output:
'    Comparing 'Aa' (00 41 00 61) and 'A   a' (00 41 00 00 00 00 00 00 00 61):
'       With String.Compare:
'          Ordinal: 97
'       With String.Equals:
'          Ordinal: False

Porównywanie porządkowe bez uwzględniania wielkości liter jest kolejnym najbardziej rygorystycznym podejściem.Case-insensitive ordinal comparisons are the next most conservative approach. Te porównania ignorują większość wielkości liter; na przykład "Windows" dopasowuje "Windows".These comparisons ignore most casing; for example, "windows" matches "Windows". W przypadku znaków ASCII te zasady są równoważne z StringComparison.Ordinal, z tą różnicą, że ignoruje zwykłe wielkości liter ASCII.When dealing with ASCII characters, this policy is equivalent to StringComparison.Ordinal, except that it ignores the usual ASCII casing. W związku z tym każdy znak w [A, Z] (\u0041-\u005A) pasuje do odpowiadającego mu znaku w [a, z] (\u0061-\007A).Therefore, any character in [A, Z] (\u0041-\u005A) matches the corresponding character in [a,z] (\u0061-\007A). Wielkość liter poza zakresem ASCII używa tabel niezmiennej kultury.Casing outside the ASCII range uses the invariant culture's tables. W związku z tym następujące porównanie:Therefore, the following comparison:

String.Compare(strA, strB, StringComparison.OrdinalIgnoreCase);
String.Compare(strA, strB, StringComparison.OrdinalIgnoreCase)

jest odpowiednikiem (ale szybszym niż) tego porównania:is equivalent to (but faster than) this comparison:

String.Compare(strA.ToUpperInvariant(), strB.ToUpperInvariant(), 
               StringComparison.Ordinal);
String.Compare(strA.ToUpperInvariant(), strB.ToUpperInvariant(), 
               StringComparison.Ordinal)

Te porównania są nadal bardzo szybkie.These comparisons are still very fast.

Uwaga

Zachowanie ciągu w systemie plików, kluczach rejestru i wartościach oraz zmienne środowiskowe najlepiej reprezentowane przez StringComparison.OrdinalIgnoreCaseprogram.The string behavior of the file system, registry keys and values, and environment variables is best represented by StringComparison.OrdinalIgnoreCase.

Zarówno StringComparison.Ordinal , StringComparison.OrdinalIgnoreCase jak i używają wartości binarnych, są one najlepiej dopasowane do dopasowywania.Both StringComparison.Ordinal and StringComparison.OrdinalIgnoreCase use the binary values directly, and are best suited for matching. Gdy nie masz pewności co do ustawień porównania, użyj jednej z tych dwóch wartości.When you are not sure about your comparison settings, use one of these two values. Jednak ze względu na to, że wykonują porównywanie bajt po bajcie, nie sortuje według języka porządku sortowania (na przykład słownika angielskiego), ale według binarnej kolejności sortowania.However, because they perform a byte-by-byte comparison, they do not sort by a linguistic sort order (like an English dictionary) but by a binary sort order. Wyniki mogą wyglądać nieparzystie w większości kontekstów, jeśli są wyświetlane użytkownikom.The results may look odd in most contexts if displayed to users.

Semantyka porządkowa jest wartością domyślną String.Equals dla przeciążeń, które StringComparison nie zawierają argumentu (łącznie z operatorem równości).Ordinal semantics are the default for String.Equals overloads that do not include a StringComparison argument (including the equality operator). W każdym przypadku zalecamy wywołanie przeciążenia z StringComparison parametrem.In any case, we recommend that you call an overload that has a StringComparison parameter.

Operacje na ciągach, które używają kultury niezmiennejString Operations that Use the Invariant Culture

Porównania z kulturą niezmienną używają CompareInfo właściwości zwróconej przez właściwość statyczną. CultureInfo.InvariantCultureComparisons with the invariant culture use the CompareInfo property returned by the static CultureInfo.InvariantCulture property. Takie zachowanie jest takie samo w przypadku wszystkich systemów; tłumaczy wszelkie znaki spoza zakresu na to, co jest uważane za równoważne znaki niezmienne.This behavior is the same on all systems; it translates any characters outside its range into what it believes are equivalent invariant characters. Te zasady mogą być przydatne do obsługi jednego zestawu zachowań ciągów między kulturami, ale często zapewniają nieoczekiwane wyniki.This policy can be useful for maintaining one set of string behavior across cultures, but it often provides unexpected results.

Porównania bez uwzględniania wielkości liter z kulturą niezmienną należy używać CompareInfo właściwości statycznej zwróconej CultureInfo.InvariantCulture przez właściwość statyczną dla informacji porównawczych.Case-insensitive comparisons with the invariant culture use the static CompareInfo property returned by the static CultureInfo.InvariantCulture property for comparison information as well. Wszelkie różnice wielkości liter między tymi przetłumaczonymi znakami są ignorowane.Any case differences among these translated characters are ignored.

Porównania, które StringComparison.InvariantCulture używają StringComparison.Ordinal i działają identycznie na ciągach ASCII.Comparisons that use StringComparison.InvariantCulture and StringComparison.Ordinal work identically on ASCII strings. Jednak program StringComparison.InvariantCulture podejmuje decyzje językowe, które mogą nie być odpowiednie dla ciągów, które muszą być interpretowane jako zestaw bajtów.However, StringComparison.InvariantCulture makes linguistic decisions that might not be appropriate for strings that have to be interpreted as a set of bytes. Obiekt sprawia, Compare że metoda interpretuje niektóre zestawy znaków jako równoważne. CultureInfo.InvariantCulture.CompareInfoThe CultureInfo.InvariantCulture.CompareInfo object makes the Compare method interpret certain sets of characters as equivalent. Na przykład następująca równoważność jest prawidłowa dla niezmiennej kultury:For example, the following equivalence is valid under the invariant culture:

InvariantCulture: a + ̊ = aInvariantCulture: a + ̊ = å

Mała litera "a" (\u0061), gdy jest obok znaku ŁĄCZĄCego powyżej znak "+" ̊ "(\u030a), jest interpretowana jako mała litera A z PIERŚCIENIem powyżej znaku" a "(\u00e5).The LATIN SMALL LETTER A character "a" (\u0061), when it is next to the COMBINING RING ABOVE character "+ " ̊" (\u030a), is interpreted as the LATIN SMALL LETTER A WITH RING ABOVE character "å" (\u00e5). Jak pokazano na poniższym przykładzie, to zachowanie różni się od porównania liczb porządkowych.As the following example shows, this behavior differs from ordinal comparison.

string separated = "\u0061\u030a";
string combined = "\u00e5";
      
Console.WriteLine("Equal sort weight of {0} and {1} using InvariantCulture: {2}",
                  separated, combined, 
                  String.Compare(separated, combined, 
                                 StringComparison.InvariantCulture) == 0);

Console.WriteLine("Equal sort weight of {0} and {1} using Ordinal: {2}",
                  separated, combined,
                  String.Compare(separated, combined, 
                                 StringComparison.Ordinal) == 0);
// The example displays the following output:
//    Equal sort weight of a° and å using InvariantCulture: True
//    Equal sort weight of a° and å using Ordinal: False      
Dim separated As String = ChrW(&h61) + ChrW(&h30a)
Dim combined As String = ChrW(&he5)
      
Console.WriteLine("Equal sort weight of {0} and {1} using InvariantCulture: {2}", _
                  separated, combined, _
                  String.Compare(separated, combined, _ 
                                 StringComparison.InvariantCulture) = 0)

Console.WriteLine("Equal sort weight of {0} and {1} using Ordinal: {2}", _
                  separated, combined, _
                  String.Compare(separated, combined, _
                                 StringComparison.Ordinal) = 0)
' The example displays the following output:
'    Equal sort weight of a° and å using InvariantCulture: True
'    Equal sort weight of a° and å using Ordinal: False

W przypadku interpretacji nazw plików, plików cookie lub innych elementów, w których może się pojawić kombinacja, taka jak "a", porównania porządkowe nadal zapewniają najbardziej przejrzyste i niedopasowane zachowanie.When interpreting file names, cookies, or anything else where a combination such as "å" can appear, ordinal comparisons still offer the most transparent and fitting behavior.

W przypadku niezmiennej kultura ma bardzo kilka właściwości, które ułatwiają porównywanie.On balance, the invariant culture has very few properties that make it useful for comparison. Jest to porównywane w sposób istotny, który uniemożliwia mu zagwarantowanie pełnego równoważności symbolicznej, ale nie jest to możliwe do wyświetlania w żadnej kulturze.It does comparison in a linguistically relevant manner, which prevents it from guaranteeing full symbolic equivalence, but it is not the choice for display in any culture. Jedną z kilku powodów użycia StringComparison.InvariantCulture do porównania jest utrwalanie uporządkowanych danych dla różnych kulturowo identycznych ekranów.One of the few reasons to use StringComparison.InvariantCulture for comparison is to persist ordered data for a cross-culturally identical display. Na przykład jeśli plik danych o dużym rozmiarze zawierający listę posortowanych identyfikatorów dla wyświetlania towarzyszy aplikacji, dodanie do tej listy będzie wymagało wstawienia z sortowaniem w stylu niezmiennym.For example, if a large data file that contains a list of sorted identifiers for display accompanies an application, adding to this list would require an insertion with invariant-style sorting.

Powrót do początkuBack to top

Wybieranie elementu StringComparison (porównywania ciągów tekstowych) do metody wywołaniaChoosing a StringComparison Member for Your Method Call

Poniższa tabela zawiera opis mapowania z kontekstu ciągu semantycznego do StringComparison elementu członkowskiego wyliczenia.The following table outlines the mapping from semantic string context to a StringComparison enumeration member.

DaneData ZachowanieBehavior Odpowiadający system. StringComparisonCorresponding System.StringComparison

valuevalue
Identyfikatory wewnętrzne z uwzględnieniem wielkości liter.Case-sensitive internal identifiers.

Identyfikatory z uwzględnieniem wielkości liter w standardach, takich jak XML i HTTP.Case-sensitive identifiers in standards such as XML and HTTP.

Ustawienia związane z zabezpieczeniami z uwzględnieniem wielkości liter.Case-sensitive security-related settings.
Identyfikator niebędący językiem, gdzie bajty są dokładnie zgodne.A non-linguistic identifier, where bytes match exactly. Ordinal
Identyfikatory wewnętrzne bez uwzględniania wielkości liter.Case-insensitive internal identifiers.

Identyfikatory bez uwzględniania wielkości liter w standardach, takich jak XML i HTTP.Case-insensitive identifiers in standards such as XML and HTTP.

Ścieżki plików.File paths.

Klucze i wartości rejestru.Registry keys and values.

Zmienne środowiskowe.Environment variables.

Identyfikatory zasobów (na przykład nazwy uchwytów).Resource identifiers (for example, handle names).

Ustawienia związane z zabezpieczeniami bez uwzględniania wielkości liter.Case-insensitive security-related settings.
Identyfikator niebędący językiem, gdzie przypadek jest nieistotny; szczególnie dane przechowywane w większości usług systemu Windows.A non-linguistic identifier, where case is irrelevant; especially data stored in most Windows system services. OrdinalIgnoreCase
Pewne utrwalone, językowe dane.Some persisted, linguistically relevant data.

Wyświetlanie danych lingwistycznych, które wymagają stałego porządku sortowania.Display of linguistic data that requires a fixed sort order.
Kulturowo niezależny od dane, które nadal są istotne dla języka.Culturally agnostic data that still is linguistically relevant. InvariantCulture

—lub—-or-

InvariantCultureIgnoreCase
Dane wyświetlane użytkownikowi.Data displayed to the user.

Większość danych wejściowych użytkownika.Most user input.
Dane wymagające lokalnego języka.Data that requires local linguistic customs. CurrentCulture

—lub—-or-

CurrentCultureIgnoreCase

Powrót do początkuBack to top

Typowe metody porównywania ciągów w programie .NETCommon String Comparison Methods in .NET

W poniższych sekcjach opisano metody, które są najczęściej używane do porównywania ciągów.The following sections describe the methods that are most commonly used for string comparison.

Funkcja String.CompareString.Compare

Domyślna interpretacja StringComparison.CurrentCulture:.Default interpretation: StringComparison.CurrentCulture.

Jako że operacja najważniejsza do interpretacji ciągów, wszystkie wystąpienia tych wywołań metod powinny być badane w celu określenia, czy ciągi powinny być interpretowane zgodnie z bieżącą kulturą, czy też odwoływać się od kultury (symbolicznie).As the operation most central to string interpretation, all instances of these method calls should be examined to determine whether strings should be interpreted according to the current culture, or dissociated from the culture (symbolically). Zwykle jest to ostatni i StringComparison.Ordinal zamiast tego należy użyć porównania.Typically, it is the latter, and a StringComparison.Ordinal comparison should be used instead.

Klasa, która jest zwracana CultureInfo.CompareInfo przez Compare właściwość, również zawiera metodę, która zapewnia dużą liczbę pasujących opcji (numer porządkowy, ignorowanie białego znaku, ignorowanie typu kana itd.) za pomocą CompareOptionsflagi System.Globalization.CompareInfo Licznik.The System.Globalization.CompareInfo class, which is returned by the CultureInfo.CompareInfo property, also includes a Compare method that provides a large number of matching options (ordinal, ignoring white space, ignoring kana type, and so on) by means of the CompareOptions flag enumeration.

Funkcja String.CompareToString.CompareTo

Domyślna interpretacja StringComparison.CurrentCulture:.Default interpretation: StringComparison.CurrentCulture.

Ta metoda obecnie nie oferuje przeciążenia, które określa StringComparison typ.This method does not currently offer an overload that specifies a StringComparison type. Zwykle jest możliwe przekonwertowanie tej metody na zalecaną String.Compare(String, String, StringComparison) formę.It is usually possible to convert this method to the recommended String.Compare(String, String, StringComparison) form.

Typy, które IComparable implementują IComparable<T> interfejsy i implementują tę metodę.Types that implement the IComparable and IComparable<T> interfaces implement this method. Ponieważ nie oferuje opcji StringComparison parametru, implementacja typów często zezwala użytkownikowi na StringComparer określenie w konstruktorze.Because it does not offer the option of a StringComparison parameter, implementing types often let the user specify a StringComparer in their constructor. W poniższym przykładzie zdefiniowano FileName klasę, której Konstruktor klasy StringComparer zawiera parametr.The following example defines a FileName class whose class constructor includes a StringComparer parameter. Ten StringComparer obiekt jest następnie używany FileName.CompareTo w metodzie.This StringComparer object is then used in the FileName.CompareTo method.

using System;

public class FileName : IComparable
{
   string fname;
   StringComparer comparer; 
   
   public FileName(string name, StringComparer comparer)
   {
      if (String.IsNullOrEmpty(name))
         throw new ArgumentNullException("name");

      this.fname = name;
      
      if (comparer != null)
         this.comparer = comparer;
      else
         this.comparer = StringComparer.OrdinalIgnoreCase;
   }

   public string Name
   {
      get { return fname; }
   }
   
   public int CompareTo(object obj)
   {
      if (obj == null) return 1;

      if (! (obj is FileName))
         return comparer.Compare(this.fname, obj.ToString());
      else
         return comparer.Compare(this.fname, ((FileName) obj).Name);
   }
}
Public Class FileName : Implements IComparable
   Dim fname As String
   Dim comparer As StringComparer 
   
   Public Sub New(name As String, comparer As StringComparer)
      If String.IsNullOrEmpty(name) Then
         Throw New ArgumentNullException("name")
      End If

      Me.fname = name
      
      If comparer IsNot Nothing Then
         Me.comparer = comparer
      Else
         Me.comparer = StringComparer.OrdinalIgnoreCase
      End If      
   End Sub

   Public ReadOnly Property Name As String
      Get
         Return fname
      End Get   
   End Property
   
   Public Function CompareTo(obj As Object) As Integer _
          Implements IComparable.CompareTo
      If obj Is Nothing Then Return 1

      If Not TypeOf obj Is FileName Then
         obj = obj.ToString()
      Else
         obj = CType(obj, FileName).Name
      End If         
      Return comparer.Compare(Me.fname, obj)
   End Function
End Class

Funkcja String.EqualsString.Equals

Domyślna interpretacja StringComparison.Ordinal:.Default interpretation: StringComparison.Ordinal.

Klasa umożliwia przetestowanie pod kątem równości przez wywołanie Equals metody statycznej lub przeciążenia lub użycie statycznego operatora równości. StringThe String class lets you test for equality by calling either the static or instance Equals method overloads, or by using the static equality operator. Przeciążenia i operator domyślnie używają porównania porządkowego.The overloads and operator use ordinal comparison by default. Mimo to nadal zalecamy wywołanie przeciążenia, które jawnie określa typ nawet w StringComparison przypadku, gdy chcesz wykonać porównanie porządkowe; ułatwia to wyszukiwanie w kodzie dla określonej interpretacji ciągów.However, we still recommend that you call an overload that explicitly specifies the StringComparison type even if you want to perform an ordinal comparison; this makes it easier to search code for a certain string interpretation.

String.ToUpper i String.ToLowerString.ToUpper and String.ToLower

Domyślna interpretacja StringComparison.CurrentCulture:.Default interpretation: StringComparison.CurrentCulture.

Należy zachować ostrożność w przypadku korzystania z tych metod, ponieważ wymuszanie ciągu do wielkich lub małych liter jest często używane jako mała normalizacja do porównywania ciągów, niezależnie od wielkości liter.You should be careful when you use these methods, because forcing a string to a uppercase or lowercase is often used as a small normalization for comparing strings regardless of case. Jeśli tak, rozważ użycie porównania bez uwzględniania wielkości liter.If so, consider using a case-insensitive comparison.

Dostępne są String.ToLowerInvariant również metody i.String.ToUpperInvariantThe String.ToUpperInvariant and String.ToLowerInvariant methods are also available. ToUpperInvariantjest standardowym sposobem normalizacji wielkości liter.ToUpperInvariant is the standard way to normalize case. Porównania wykonywane przy StringComparison.OrdinalIgnoreCase użyciu są zachowaniem składu dwóch wywołań: wywoływanie ToUpperInvariant dla obu argumentów ciągów i wykonywanie porównania przy użyciu StringComparison.Ordinal.Comparisons made using StringComparison.OrdinalIgnoreCase are behaviorally the composition of two calls: calling ToUpperInvariant on both string arguments, and doing a comparison using StringComparison.Ordinal.

Przeciążenia są również dostępne do przekonwertowania na wielkie i małe litery w określonej kulturze, przekazując CultureInfo obiekt, który reprezentuje tę kulturę do metody.Overloads are also available for converting to uppercase and lowercase in a specific culture, by passing a CultureInfo object that represents that culture to the method.

Char.ToUpper i Char.ToLowerChar.ToUpper and Char.ToLower

Domyślna interpretacja StringComparison.CurrentCulture:.Default interpretation: StringComparison.CurrentCulture.

Metody te działają podobnie String.ToUpper jak metody i String.ToLower opisane w poprzedniej sekcji.These methods work similarly to the String.ToUpper and String.ToLower methods described in the previous section.

String.StartsWith i String.EndsWithString.StartsWith and String.EndsWith

Domyślna interpretacja StringComparison.CurrentCulture:.Default interpretation: StringComparison.CurrentCulture.

Domyślnie obie te metody wykonują porównanie z uwzględnieniem kultury.By default, both of these methods perform a culture-sensitive comparison.

String.IndexOf i String.LastIndexOfString.IndexOf and String.LastIndexOf

Domyślna interpretacja StringComparison.CurrentCulture:.Default interpretation: StringComparison.CurrentCulture.

Brak spójności w sposobie wykonywania porównań przez domyślne przeciążenia tych metod.There is a lack of consistency in how the default overloads of these methods perform comparisons. Wszystkie String.IndexOf Char i String.IndexOf String.LastIndexOf String metody, które zawierają parametr, wykonują porównanie porządkowe, ale domyślne i metody, które zawierają parametr, są zależne od kultury String.LastIndexOf prowadzone.All String.IndexOf and String.LastIndexOf methods that include a Char parameter perform an ordinal comparison, but the default String.IndexOf and String.LastIndexOf methods that include a String parameter perform a culture-sensitive comparison.

W przypadku wywołania String.IndexOf(String) metody lub String.LastIndexOf(String) i przekazania do niej ciągu w celu zlokalizowania w bieżącym wystąpieniu zalecamy wywołanie StringComparison przeciążenia, które jawnie określa typ.If you call the String.IndexOf(String) or String.LastIndexOf(String) method and pass it a string to locate in the current instance, we recommend that you call an overload that explicitly specifies the StringComparison type. Przeciążenia, które zawierają Char argument, nie pozwalają na StringComparison określenie typu.The overloads that include a Char argument do not allow you to specify a StringComparison type.

Powrót do początkuBack to top

Metody, które pośrednio wykonują porównywania ciąguMethods that Perform String Comparison Indirectly

Niektóre metody niebędące ciągami, które mają porównanie ciągów jako operacji centralnej StringComparer używają typu.Some non-string methods that have string comparison as a central operation use the StringComparer type. Klasa zawiera sześć właściwości statycznych, które zwracają StringComparer wystąpienia, StringComparer.Compare których metody wykonują następujące typy porównań ciągów: StringComparerThe StringComparer class includes six static properties that return StringComparer instances whose StringComparer.Compare methods perform the following types of string comparisons:

Array.Sort i Array.BinarySearchArray.Sort and Array.BinarySearch

Domyślna interpretacja StringComparison.CurrentCulture:.Default interpretation: StringComparison.CurrentCulture.

W przypadku przechowywania danych w kolekcji lub odczytywania utrwalonych danych z pliku lub bazy danych do kolekcji, przełączenie bieżącej kultury może spowodować unieważnienie niezmiennych w kolekcji.When you store any data in a collection, or read persisted data from a file or database into a collection, switching the current culture can invalidate the invariants in the collection. Array.BinarySearch Metoda zakłada, że elementy w tablicy, które mają być przeszukiwane, są już posortowane.The Array.BinarySearch method assumes that the elements in the array to be searched are already sorted. Aby posortować dowolny element ciągu w tablicy, Array.Sort Metoda String.Compare wywołuje metodę w celu uporządkowania poszczególnych elementów.To sort any string element in the array, the Array.Sort method calls the String.Compare method to order individual elements. Użycie funkcji porównującej uwzględniającej kulturę może być niebezpieczne, jeśli kultura zmieni się między posortowaną tablicą a jego zawartością jest przeszukiwana.Using a culture-sensitive comparer can be dangerous if the culture changes between the time that the array is sorted and its contents are searched. Na przykład, w poniższym kodzie, magazyn i pobieranie działają na porównującej, który jest dostarczany niejawnie przez Thread.CurrentThread.CurrentCulture właściwość.For example, in the following code, storage and retrieval operate on the comparer that is provided implicitly by the Thread.CurrentThread.CurrentCulture property. Jeśli kultura może zmienić między wywołaniami do StoreNames i DoesNameExist, a zwłaszcza jeśli zawartość tablicy jest utrwalana między dwoma wywołaniami metod, wyszukiwanie binarne może zakończyć się niepowodzeniem.If the culture can change between the calls to StoreNames and DoesNameExist, and especially if the array contents are persisted somewhere between the two method calls, the binary search may fail.

// Incorrect.
string []storedNames;

public void StoreNames(string [] names)
{
   int index = 0;
   storedNames = new string[names.Length];

   foreach (string name in names)
   {
      this.storedNames[index++] = name;
   }

   Array.Sort(names); // Line A.
}

public bool DoesNameExist(string name)
{
   return (Array.BinarySearch(this.storedNames, name) >= 0);  // Line B.
}
' Incorrect.
Dim storedNames() As String

Public Sub StoreNames(names() As String)
   Dim index As Integer = 0
   ReDim storedNames(names.Length - 1)
   
   For Each name As String In names
      Me.storedNames(index) = name
      index+= 1
   Next
   
   Array.Sort(names)          ' Line A.
End Sub

Public Function DoesNameExist(name As String) As Boolean
   Return Array.BinarySearch(Me.storedNames, name) >= 0      ' Line B.
End Function

W poniższym przykładzie zostanie wyświetlona zalecana odmiana, która używa tej samej wartości porządkowej (bez uwzględniania kultury) zarówno do sortowania, jak i do przeszukiwania tablicy.A recommended variation appears in the following example, which uses the same ordinal (culture-insensitive) comparison method both to sort and to search the array. Kod zmiany jest widoczny w wierszach oznaczonych Line A i Line B w dwóch przykładach.The change code is reflected in the lines labeled Line A and Line B in the two examples.

// Correct.
string []storedNames;

public void StoreNames(string [] names)
{
   int index = 0;
   storedNames = new string[names.Length];

   foreach (string name in names)
   {
      this.storedNames[index++] = name;
   }

   Array.Sort(names, StringComparer.Ordinal);  // Line A.
}

public bool DoesNameExist(string name)
{
   return (Array.BinarySearch(this.storedNames, name, StringComparer.Ordinal) >= 0);  // Line B.
}
' Correct.
Dim storedNames() As String

Public Sub StoreNames(names() As String)
   Dim index As Integer = 0
   ReDim storedNames(names.Length - 1)
   
   For Each name As String In names
      Me.storedNames(index) = name
      index+= 1
   Next
   
   Array.Sort(names, StringComparer.Ordinal)           ' Line A.
End Sub

Public Function DoesNameExist(name As String) As Boolean
   Return Array.BinarySearch(Me.storedNames, name, StringComparer.Ordinal) >= 0      ' Line B.
End Function

Jeśli te dane są utrwalane i przenoszone między kulturami, a sortowanie służy do prezentowania tych danych użytkownikowi, można rozważyć użycie StringComparison.InvariantCulture, który działa w sposób językowy dla lepszych danych wyjściowych użytkownika, ale nie ma wpływ na zmiany w kulturze.If this data is persisted and moved across cultures, and sorting is used to present this data to the user, you might consider using StringComparison.InvariantCulture, which operates linguistically for better user output but is unaffected by changes in culture. Poniższy przykład modyfikuje dwa poprzednie przykłady, aby użyć niezmiennej kultury do sortowania i przeszukiwania tablicy.The following example modifies the two previous examples to use the invariant culture for sorting and searching the array.

// Correct.
string []storedNames;

public void StoreNames(string [] names)
{
   int index = 0;
   storedNames = new string[names.Length];

   foreach (string name in names)
   {
      this.storedNames[index++] = name;
   }

   Array.Sort(names, StringComparer.InvariantCulture);  // Line A.
}

public bool DoesNameExist(string name)
{
   return (Array.BinarySearch(this.storedNames, name, StringComparer.InvariantCulture) >= 0);  // Line B.
}
' Correct.
Dim storedNames() As String

Public Sub StoreNames(names() As String)
   Dim index As Integer = 0
   ReDim storedNames(names.Length - 1)
   
   For Each name As String In names
      Me.storedNames(index) = name
      index+= 1
   Next
   
   Array.Sort(names, StringComparer.InvariantCulture)           ' Line A.
End Sub

Public Function DoesNameExist(name As String) As Boolean
   Return Array.BinarySearch(Me.storedNames, name, StringComparer.InvariantCulture) >= 0      ' Line B.
End Function

Przykład kolekcji: Hashtable — KonstruktorCollections Example: Hashtable Constructor

Ciągi mieszania zawierają drugi przykład operacji, na które ma wpływ, w jaki sposób ciągi są porównywane.Hashing strings provides a second example of an operation that is affected by the way in which strings are compared.

Poniższy przykład tworzy wystąpienie Hashtable obiektu przez przekazanie go do StringComparer obiektu StringComparer.OrdinalIgnoreCase , który jest zwracany przez właściwość.The following example instantiates a Hashtable object by passing it the StringComparer object that is returned by the StringComparer.OrdinalIgnoreCase property. Ponieważ Klasa StringComparer , która pochodzi od StringComparer implementuje IEqualityComparer interfejs, jego GetHashCode Metoda jest używana do obliczania kodu skrótu ciągów w tabeli skrótów.Because a class StringComparer that is derived from StringComparer implements the IEqualityComparer interface, its GetHashCode method is used to compute the hash code of strings in the hash table.

const int initialTableCapacity = 100;
Hashtable h;

public void PopulateFileTable(string directory)
{
   h = new Hashtable(initialTableCapacity, 
                     StringComparer.OrdinalIgnoreCase);
         
   foreach (string file in Directory.GetFiles(directory))
         h.Add(file, File.GetCreationTime(file));
}

public void PrintCreationTime(string targetFile)
{
   Object dt = h[targetFile];
   if (dt != null)
   {
      Console.WriteLine("File {0} was created at time {1}.",
         targetFile, 
         (DateTime) dt);
   }
   else
   {
      Console.WriteLine("File {0} does not exist.", targetFile);
   }
}
Const initialTableCapacity As Integer = 100
Dim h As Hashtable

Public Sub PopulateFileTable(dir As String)
   h = New Hashtable(initialTableCapacity, _
                     StringComparer.OrdinalIgnoreCase)
                     
   For Each filename As String In Directory.GetFiles(dir)
      h.Add(filename, File.GetCreationTime(filename))
   Next                        
End Sub

Public Sub PrintCreationTime(targetFile As String)
   Dim dt As Object = h(targetFile)
   If dt IsNot Nothing Then
      Console.WriteLine("File {0} was created at {1}.", _
         targetFile, _
         CDate(dt))
   Else
      Console.WriteLine("File {0} does not exist.", targetFile)
   End If
End Sub  

Powrót do początkuBack to top

Wyświetlanie i utrzymanie sformatowanych danychDisplaying and Persisting Formatted Data

W przypadku wyświetlania danych niebędących ciągami, takich jak liczby i daty i godziny, sformatuj je przy użyciu ustawień kultury użytkownika.When you display non-string data such as numbers and dates and times to users, format them by using the user's cultural settings. Domyślnie następujące wszystkie używają bieżącej kultury wątku w operacjach formatowania:By default, the following all use the current thread culture in formatting operations:

  • Ciągi interpolowane obsługiwane przez kompilatory C# i Visual Basic .Interpolated strings supported by the C# and Visual Basic compilers.

  • Operacje łączenia ciągów wykorzystujące operatory łączenia C# lub Visual Basic lub bezpośrednio wywołujące String.Concat metodę.String concatenation operations that use the C# or Visual Basic concatenation operators or that call the String.Concat method directly.

  • String.Format Metoda.The String.Format method.

  • ToString Metody typów liczbowych i typów dat i godzin.The ToString methods of the numeric types and the date and time types.

Aby jawnie określić, że ciąg powinien być sformatowany przy użyciu konwencji określonej kultury lub niezmiennej kultury, można wykonać następujące czynności:To explicitly specify that a string should be formatted by using the conventions of a designated culture or the invariant culture, you can do the following:

  • Przy użyciu String.Format metod i ToString Wywołaj Przeciążenie, które ma DateTime.ToString(IFormatProvider) provider parametr, CultureInfo.CurrentCulture taki jak String.Format(IFormatProvider, String, Object[]) lub, i przekaż go właściwości, CultureInfo wystąpienie, które reprezentuje żądany Kultura lub CultureInfo.InvariantCulture właściwość.When using the String.Format and ToString methods, call an overload that has a provider parameter, such as String.Format(IFormatProvider, String, Object[]) or DateTime.ToString(IFormatProvider), and pass it the CultureInfo.CurrentCulture property, a CultureInfo instance that represents the desired culture, or the CultureInfo.InvariantCulture property.

  • W przypadku łączenia ciągów nie Zezwalaj kompilatorowi na wykonywanie jakichkolwiek niejawnych konwersji.For string concatenation, do not allow the compiler to perform any implicit conversions. Zamiast tego należy wykonać jawną konwersję, ToString wywołując Przeciążenie provider z parametrem.Instead, perform an explicit conversion by calling a ToString overload that has a provider parameter. Na przykład kompilator niejawnie używa bieżącej kultury podczas konwertowania Double wartości na ciąg w poniższym C# kodzie:For example, the compiler implicitly uses the current culture when converting a Double value to a string in the following C# code:

    string concat1 = "The amount is " + 126.03 + ".";
    Console.WriteLine(concat1);
    

    Zamiast tego można jawnie określić kulturę, której konwencje formatowania są używane w konwersji, wywołując Double.ToString(IFormatProvider) metodę, tak jak w poniższym C# kodzie:Instead, you can explicitly specify the culture whose formatting conventions are used in the conversion by calling the Double.ToString(IFormatProvider) method, as the following C# code does:

    string concat2 = "The amount is " + 126.03.ToString(CultureInfo.InvariantCulture) + ".";
    Console.WriteLine(concat2);
    
  • W przypadku interpolacji ciągów zamiast przypisywania do String wystąpienia ciągu interpolowanego, należy przypisać go FormattableStringdo.For string interpolation, rather than assigning an interpolated string to a String instance, assign it to a FormattableString. Następnie można wywołać FormattableString.ToString() metodę generującą ciąg wynikowy, który odzwierciedla konwencje bieżącej kultury, lub FormattableString.ToString(IFormatProvider) wywołać metodę, aby utworzyć ciąg wynikowy, który odzwierciedla konwencje określonej kultury.You can then call its FormattableString.ToString() method produce a result string that reflects the conventions of the current culture, or you can call the FormattableString.ToString(IFormatProvider) method to produce a result string that reflects the conventions of a specified culture. Możesz również przekazać ciąg formatu do metody statycznej FormattableString.Invariant , aby utworzyć ciąg wynikowy, który odzwierciedla konwencje niezmiennej kultury.You can also pass the formattable string to the static FormattableString.Invariant method to produce a result string that reflects the conventions of the invariant culture. To podejście pokazano w poniższym przykładzie.The following example illustrates this approach. (Dane wyjściowe z przykładu odzwierciedlają bieżącą kulturę en-US).(The output from the example reflects a current culture of en-US.)

    using System;
    using System.Globalization;
    
    class Program
    {
        static void Main()
        {
            Decimal value = 126.03m;
            FormattableString amount = $"The amount is {value:C}"; 
            Console.WriteLine(amount.ToString());
            Console.WriteLine(amount.ToString(new CultureInfo("fr-FR")));
            Console.WriteLine(FormattableString.Invariant(amount));
        }
    }
    // The example displays the following output:
    //    The amount is $126.03
    //    The amount is 126,03 €
    //    The amount is ¤126.03
    
    Imports System.Globalization
    
    Module Program
        Sub Main()
            Dim value As Decimal = 126.03
            Dim amount As FormattableString = $"The amount is {value:C}" 
            Console.WriteLine(amount.ToString())
            Console.WriteLine(amount.ToString(new CultureInfo("fr-FR")))
            Console.WriteLine(FormattableString.Invariant(amount))
        End Sub
    End Module
    ' The example displays the following output:
    '    The amount is $126.03
    '    The amount is 126,03 €
    '    The amount is ¤126.03
    

Dane niebędące ciągami mogą być utrwalane jako dane binarne lub dane sformatowane.You can persist non-string data either as binary data or as formatted data. Jeśli zdecydujesz się zapisać ją jako sformatowane dane, należy wywołać Przeciążenie metody formatowania, które zawiera provider parametr i przekazać go do CultureInfo.InvariantCulture właściwości.If you choose to save it as formatted data, you should call a formatting method overload that includes a provider parameter and pass it the CultureInfo.InvariantCulture property. Kultura niezmienna zapewnia spójny format sformatowanych danych, które są niezależne od kultury i maszyny.The invariant culture provides a consistent format for formatted data that is independent of culture and machine. W przeciwieństwie do utrwalania danych, które są formatowane przy użyciu kultur innych niż kultura niezmienna, ma wiele ograniczeń:In contrast, persisting data that is formatted by using cultures other than the invariant culture has a number of limitations:

  • Dane mogą być bezużyteczne, jeśli są pobierane w systemie, który ma inną kulturę, lub jeśli użytkownik bieżącego systemu zmienia bieżącą kulturę i próbuje pobrać dane.The data is likely to be unusable if it is retrieved on a system that has a different culture, or if the user of the current system changes the current culture and tries to retrieve the data.

  • Właściwości kultury na określonym komputerze mogą różnić się od wartości standardowych.The properties of a culture on a specific computer can differ from standard values. W dowolnym momencie użytkownik może dostosować ustawienia wyświetlania z uwzględnieniem kultury.At any time, a user can customize culture-sensitive display settings. W związku z tym sformatowane dane zapisane w systemie mogą nie zostać odczytane, gdy użytkownik dostosowuje ustawienia kulturowe.Because of this, formatted data that is saved on a system may not be readable after the user customizes cultural settings. Przenośność sformatowanych danych między komputerami może być jeszcze bardziej ograniczona.The portability of formatted data across computers is likely to be even more limited.

  • Międzynarodowe, regionalne lub krajowe standardy, które regulują formatowanie liczb lub dat i godzin zmiany czasu, i te zmiany są włączane do aktualizacji systemu operacyjnego Windows.International, regional, or national standards that govern the formatting of numbers or dates and times change over time, and these changes are incorporated into Windows operating system updates. W przypadku zmiany Konwencji formatowania dane sformatowane przy użyciu poprzednich Konwencji mogą stać się nieczytelne.When formatting conventions change, data that was formatted by using the previous conventions may become unreadable.

Poniższy przykład ilustruje ograniczoną przenośność, która wynika z używania formatowania z uwzględnieniem kultury do utrwalania danych.The following example illustrates the limited portability that results from using culture-sensitive formatting to persist data. Przykład zapisuje tablicę wartości daty i godziny do pliku.The example saves an array of date and time values to a file. Są one sformatowane przy użyciu Konwencji kultury angielskiej (Stany Zjednoczone).These are formatted by using the conventions of the English (United States) culture. Gdy aplikacja zmieni bieżącą kulturę wątku na francuski (Szwajcaria), próbuje odczytać zapisane wartości przy użyciu Konwencji formatowania bieżącej kultury.After the application changes the current thread culture to French (Switzerland), it tries to read the saved values by using the formatting conventions of the current culture. Próba odczytania dwóch elementów danych zgłasza FormatException wyjątek, a tablica dat zawiera teraz dwa niepoprawne elementy, które są MinValuerówne.The attempt to read two of the data items throws a FormatException exception, and the array of dates now contains two incorrect elements that are equal to MinValue.

using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;

public class Example
{
   private static string filename = @".\dates.dat";

   public static void Main()
   {
      DateTime[] dates = { new DateTime(1758, 5, 6, 21, 26, 0), 
                           new DateTime(1818, 5, 5, 7, 19, 0), 
                           new DateTime(1870, 4, 22, 23, 54, 0),  
                           new DateTime(1890, 9, 8, 6, 47, 0), 
                           new DateTime(1905, 2, 18, 15, 12, 0) }; 
      // Write the data to a file using the current culture.
      WriteData(dates);
      // Change the current culture.
      Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("fr-CH");
      // Read the data using the current culture.
      DateTime[] newDates = ReadData();
      foreach (var newDate in newDates)
         Console.WriteLine(newDate.ToString("g"));
   }
   
   private static void WriteData(DateTime[] dates) 
   {
      StreamWriter sw = new StreamWriter(filename, false, Encoding.UTF8);    
      for (int ctr = 0; ctr < dates.Length; ctr++) {
         sw.Write("{0}", dates[ctr].ToString("g", CultureInfo.CurrentCulture));
         if (ctr < dates.Length - 1) sw.Write("|");   
      }      
      sw.Close();
   }
   
   private static DateTime[] ReadData() 
   {
      bool exceptionOccurred = false;
           
      // Read file contents as a single string, then split it.
      StreamReader sr = new StreamReader(filename, Encoding.UTF8);
      string output = sr.ReadToEnd();
      sr.Close();   

      string[] values = output.Split( new char[] { '|' } );
      DateTime[] newDates = new DateTime[values.Length]; 
      for (int ctr = 0; ctr < values.Length; ctr++) {
         try {
            newDates[ctr] = DateTime.Parse(values[ctr], CultureInfo.CurrentCulture);
         }
         catch (FormatException) {
            Console.WriteLine("Failed to parse {0}", values[ctr]);
            exceptionOccurred = true;
         }
      }      
      if (exceptionOccurred) Console.WriteLine();
      return newDates;
   }
}
// The example displays the following output:
//       Failed to parse 4/22/1870 11:54 PM
//       Failed to parse 2/18/1905 3:12 PM
//       
//       05.06.1758 21:26
//       05.05.1818 07:19
//       01.01.0001 00:00
//       09.08.1890 06:47
//       01.01.0001 00:00
//       01.01.0001 00:00
Imports System.Globalization
Imports System.IO
Imports System.Text
Imports System.Threading

Module Example
   Private filename As String = ".\dates.dat"
   
   Public Sub Main()
      Dim dates() As Date = { #5/6/1758 9:26PM#, #5/5/1818 7:19AM#, _ 
                              #4/22/1870 11:54PM#, #9/8/1890 6:47AM#, _ 
                              #2/18/1905 3:12PM# }
      ' Write the data to a file using the current culture.
      WriteData(dates)
      ' Change the current culture.
      Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("fr-CH")
      ' Read the data using the current culture.
      Dim newDates() As Date = ReadData()
      For Each newDate In newDates
         Console.WriteLine(newDate.ToString("g"))
      Next
   End Sub
   
   Private Sub WriteData(dates() As Date)
      Dim sw As New StreamWriter(filename, False, Encoding.Utf8)    
      For ctr As Integer = 0 To dates.Length - 1
         sw.Write("{0}", dates(ctr).ToString("g", CultureInfo.CurrentCulture))
         If ctr < dates.Length - 1 Then sw.Write("|")   
      Next      
      sw.Close()
   End Sub
   
   Private Function ReadData() As Date()
      Dim exceptionOccurred As Boolean = False
           
      ' Read file contents as a single string, then split it.
      Dim sr As New StreamReader(filename, Encoding.Utf8)
      Dim output As String = sr.ReadToEnd()
      sr.Close()   

      Dim values() As String = output.Split( {"|"c } )
      Dim newDates(values.Length - 1) As Date 
      For ctr As Integer = 0 To values.Length - 1
         Try
            newDates(ctr) = DateTime.Parse(values(ctr), CultureInfo.CurrentCulture)
         Catch e As FormatException
            Console.WriteLine("Failed to parse {0}", values(ctr))
            exceptionOccurred = True
         End Try
      Next      
      If exceptionOccurred Then Console.WriteLine()
      Return newDates
   End Function
End Module
' The example displays the following output:
'       Failed to parse 4/22/1870 11:54 PM
'       Failed to parse 2/18/1905 3:12 PM
'       
'       05.06.1758 21:26
'       05.05.1818 07:19
'       01.01.0001 00:00
'       09.08.1890 06:47
'       01.01.0001 00:00
'       01.01.0001 00:00
'

Jeśli CultureInfo.CurrentCulture jednak zastąpisz CultureInfo.InvariantCulture właściwość w wywołaniach do DateTime.ToString(String, IFormatProvider) i DateTime.Parse(String, IFormatProvider), utrwalone dane daty i godziny zostaną pomyślnie przywrócone, jak pokazano poniżej.However, if you replace the CultureInfo.CurrentCulture property with CultureInfo.InvariantCulture in the calls to DateTime.ToString(String, IFormatProvider) and DateTime.Parse(String, IFormatProvider), the persisted date and time data is successfully restored, as the following output shows.

06.05.1758 21:26  
05.05.1818 07:19  
22.04.1870 23:54  
08.09.1890 06:47  
18.02.1905 15:12  

Zobacz takżeSee also