Jak: porównywania ciągów znaków (Podręcznik programowania C#)
Podczas porównywania ciągów, jesteś produkujących wynik, który mówi jeden ciąg jest większa lub mniejsza niż inne, lub że dwa ciągi są równe.Zasady przy pomocy których wyniki są ustalane są różne w zależności od tego, czy jest przeprowadzana porównanie porządkowe lub hodowli wrażliwych porównanie.Jest ważne, aby użyć poprawnego rodzaj porównywania do określonego zadania.
Podstawowe porównań porządkowej należy używać, kiedy trzeba porównać lub posortować wartości dwóch ciągów i bez względu na językowej konwencje.Podstawowe porównanie porządkowe (System.StringComparison.Ordinal) jest uwzględniana wielkość liter, co oznacza, że dwa ciągi musi odpowiadać znaków dla znaku: "i" nie równa się "I" lub "I".Zmiana z najczęściej używanych jest System.StringComparison.OrdinalIgnoreCase, który będzie pasował "i", "I" i "I".StringComparison.OrdinalIgnoreCaseczęsto służy do porównywania nazw plików, nazwy ścieżek, ścieżek sieciowych i wszelkich innych ciągu których wartość nie zmienia się na podstawie ustawienia regionalne komputera użytkownika.Aby uzyskać więcej informacji, zobacz System.StringComparison.
Porównania hodowli wrażliwych zazwyczaj są używane do porównywania i sortowania ciągów, które są wprowadzane przez użytkowników końcowych, ponieważ znaków i konwencje sortowania z tych ciągów może się różnić w zależności od ustawień regionalnych komputera przez użytkownika.Nawet ciągów, które zawierają identyczne znaki może przydzielać różnie w zależności od kultury bieżącego wątku.
[!UWAGA]
Podczas porównywania ciągów znaków, należy użyć metody, które jawnie określić, jakiego rodzaju porównania zamierzają wykonywać.To sprawia, że Twój kod znacznie bardziej utrzymaniu i czytelne.O ile to możliwe, należy użyć przeciążenia metody System.String i System.Array klasy tego StringComparison parametr wyliczenie, dzięki czemu można określić typ porównania wykonywać.Najlepiej unikać == i != operatorów podczas porównywania ciągów.Również unikać używania String.CompareTo metody instancji, ponieważ żaden z overloads bierze StringComparison.
Przykład
Jak poprawnie porównać ciągi, których wartości nie ulegnie zmianie, oparte na ustawieniach regionalnych komputera przez użytkownika można znaleźć w poniższym przykładzie.Co więcej, ale również pokazuje internowania string cechą języka C#.Jeśli program deklaruje dwie lub więcej zmiennych identyczny napis, kompilator przechowuje je w tym samym miejscu.Wywołując ReferenceEquals metoda, widać, że dwa ciągi odnosi się do tego samego obiektu w pamięci.Użycie String.Copy metody w celu uniknięcia internowania, jak pokazano w przykładzie.
// Internal strings that will never be localized.
string root = @"C:\users";
string root2 = @"C:\Users";
// Use the overload of the Equals method that specifies a StringComparison.
// Ordinal is the fastest way to compare two strings.
bool result = root.Equals(root2, StringComparison.Ordinal);
Console.WriteLine("Ordinal comparison: {0} and {1} are {2}", root, root2,
result ? "equal." : "not equal.");
// To ignore case means "user" equals "User". This is the same as using
// String.ToUpperInvariant on each string and then performing an ordinal comparison.
result = root.Equals(root2, StringComparison.OrdinalIgnoreCase);
Console.WriteLine("Ordinal ignore case: {0} and {1} are {2}", root, root2,
result ? "equal." : "not equal.");
// A static method is also available.
bool areEqual = String.Equals(root, root2, StringComparison.Ordinal);
// String interning. Are these really two distinct objects?
string a = "The computer ate my source code.";
string b = "The computer ate my source code.";
// ReferenceEquals returns true if both objects
// point to the same location in memory.
if (String.ReferenceEquals(a, b))
Console.WriteLine("a and b are interned.");
else
Console.WriteLine("a and b are not interned.");
// Use String.Copy method to avoid interning.
string c = String.Copy(a);
if (String.ReferenceEquals(a, c))
Console.WriteLine("a and c are interned.");
else
Console.WriteLine("a and c are not interned.");
// Output:
// Ordinal comparison: C:\users and C:\Users are not equal.
// Ordinal ignore case: C:\users and C:\Users are equal.
// a and b are interned.
// a and c are not interned.
Poniższy przykład pokazuje, jak do porównywania ciągów znaków preferowany sposób za pomocą System.String metod, które mają StringComparison wyliczenie.Należy zauważyć, że String.CompareTo wystąpienia metody nie są używane w tym polu, ponieważ żaden z overloads bierze StringComparison.
// "They dance in the street."
// Linguistically (in Windows), "ss" is equal to
// the German essetz: 'ß' character in both en-US and de-DE cultures.
string first = "Sie tanzen in die Straße.";
string second = "Sie tanzen in die Strasse.";
Console.WriteLine("First sentence is {0}", first);
Console.WriteLine("Second sentence is {0}", second);
// Store CultureInfo for the current culture. Note that the original culture
// can be set and retrieved on the current thread object.
System.Threading.Thread thread = System.Threading.Thread.CurrentThread;
System.Globalization.CultureInfo originalCulture = thread.CurrentCulture;
// Set the culture to en-US.
thread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
// For culture-sensitive comparisons, use the String.Compare
// overload that takes a StringComparison value.
int i = String.Compare(first, second, StringComparison.CurrentCulture);
Console.WriteLine("Comparing in {0} returns {1}.", originalCulture.Name, i);
// Change the current culture to Deutch-Deutchland.
thread.CurrentCulture = new System.Globalization.CultureInfo("de-DE");
i = String.Compare(first, second, StringComparison.CurrentCulture);
Console.WriteLine("Comparing in {0} returns {1}.", thread.CurrentCulture.Name, i);
// For culture-sensitive string equality, use either StringCompare as above
// or the String.Equals overload that takes a StringComparison value.
thread.CurrentCulture = originalCulture;
bool b = String.Equals(first, second, StringComparison.CurrentCulture);
Console.WriteLine("The two strings {0} equal.", b == true ? "are" : "are not");
/*
* Output:
First sentence is Sie tanzen in die Straße.
Second sentence is Sie tanzen in die Strasse.
Comparing in current culture returns 0.
The two strings are equal.
*/
Poniższy przykład pokazuje sposób sortowania i wyszukiwania ciągów znaków w tablicy w sposób hodowli wrażliwych przy użyciu statycznego Array metod, które mają System.StringComparer parametru.
class SortStringArrays
{
static void Main()
{
string[] lines = new string[]
{
@"c:\public\textfile.txt",
@"c:\public\textFile.TXT",
@"c:\public\Text.txt",
@"c:\public\testfile2.txt"
};
Console.WriteLine("Non-sorted order:");
foreach (string s in lines)
{
Console.WriteLine(" {0}", s);
}
Console.WriteLine("\n\rSorted order:");
// Specify Ordinal to demonstrate the different behavior.
Array.Sort(lines, StringComparer.Ordinal);
foreach (string s in lines)
{
Console.WriteLine(" {0}", s);
}
string searchString = @"c:\public\TEXTFILE.TXT";
Console.WriteLine("Binary search for {0}", searchString);
int result = Array.BinarySearch(lines, searchString, StringComparer.OrdinalIgnoreCase);
ShowWhere<string>(lines, result);
//Console.WriteLine("{0} {1}", result > 0 ? "Found" : "Did not find", searchString);
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
// Displays where the string was found, or, if not found,
// where it would have been located.
private static void ShowWhere<T>(T[] array, int index)
{
if (index < 0)
{
// If the index is negative, it represents the bitwise
// complement of the next larger element in the array.
index = ~index;
Console.Write("Not found. Sorts between: ");
if (index == 0)
Console.Write("beginning of array and ");
else
Console.Write("{0} and ", array[index - 1]);
if (index == array.Length)
Console.WriteLine("end of array.");
else
Console.WriteLine("{0}.", array[index]);
}
else
{
Console.WriteLine("Found at index {0}.", index);
}
}
}
/*
* Output:
Non-sorted order:
c:\public\textfile.txt
c:\public\textFile.TXT
c:\public\Text.txt
c:\public\testfile2.txt
Sorted order:
c:\public\Text.txt
c:\public\testfile2.txt
c:\public\textFile.TXT
c:\public\textfile.txt
Binary search for c:\public\TEXTFILE.TXT
Found at index 2.
*/
Kolekcja klas takich jak System.Collections.Hashtable, System.Collections.Generic.Dictionary<TKey, TValue>, i System.Collections.Generic.List<T> mieć konstruktorów elementów System.StringComparer parametr, jeśli ustawiono typ elementów lub klucze string.Ogólnie rzecz biorąc, należy użyć konstruktorów te w każdym przypadku, gdy jest to możliwe, a określony żaden Ordinal lub OrdinalIgnoreCase.
Zobacz też
Informacje
System.Globalization.CultureInfo