كيفية القيام بما يلي: مقارنة السلاسل (دليل البرمجة لـ #C)

عندما تقارن السلاسل تقوم بإنتاج نتيجة تحدد ما إذا كانت السلسلة أكبر من أو أقل من الأخرى أو أن السلسلتين متساويتين. القواعد التي يتم من خلالها تحديد النتيجة تختلف استناداً إلى ما إذا كنت تنفذ مقارنة ترتيبية أو مقارنة متحسسة للثقافة. من المهم استخدام النوع الصحيح للمقارنة للمهمة المعينة.

استخدم المقارنات الترتيبية الأساسية عندما يلزم عليك مقارنة أو فرز قيم سلسلتين دون النظر إلى الاصطلاحات اللغوية. مقارنة الترتيب الأساسية (System.StringComparison.Ordinal) حساسة لحالة الأحرف، وهذا يعني أنه يجب أن تتطابق السلاسل الحرف مع الحرف: "and" لا يساوي "And" أو "AND". أحد التباينات المستخدمة بشكل متكرر هو System.StringComparison.OrdinalIgnoreCase الذي يطابق "and" و "And" و "AND". يتم استخدام StringComparison.OrdinalIgnoreCase غالباً لمقارنة أسماء الملفات وأسماء المسارات ومسارات الشبكات وأية سلاسل أخرى لا تتغير قيمتها استناداً إلى لغة الكمبيوتر الخاص بالمستخدم. لمزيد من المعلومات، راجع System.StringComparison.

المقارنات المتحسسة للثقافة تستخدم عادةً لمقارنة السلاسل المدخلة بواسطة المستخدمين النهائيين وفرزها لأن الأحرف وإصطلاحات الفرز لهذه السلاسل قد تختلف استناداً إلى لغة جهاز الكمبيوتر الخاص بالمستخدم. حتى السلاسل التي تحتوي على أحرف متطابقة قد تقوم بالفرز بشكل مختلف استناداً إلى ثقافة مسار التنفيذ الحالي.

ملاحظة

عندما تقارن السلاسل يجب عليك استخدام الأساليب التي تحدد بشكل واضح نوع المقارنة الذي تنوي إجراؤه. وذلك يجعل تعليماتك البرمجية أكثر قابلية للعناية وأكثر قابلية للقراءة. قدر الإمكان، استخدم الأساليب التي تم التحميل الزائد لها من الفئات System.String و System.Array التي تأخذ معلمة التعداد StringComparison بحيث يمكنك تحديد نوع المقارنة للتنفيذ. من الأفضل تجنب استخدام عوامل التشغيل == و != عند مقارنة السلاسل. بالإضافة إلى ذلك، تجنب استخدام أساليب المثيل String.CompareTo لأنه لا تأخذ أيٌّ من الأساليب التي تم التحميل الزائد لها StringComparison.

مثال

يظهر المثال التالي كيفية مقارنة السلاسل بشكل صحيح ذات القيم التي لا تتغير استناداً إلى لغة الكمبيوتر الخاص بالمستخدم. بالإضافة إلى ذلك، فإنه يوضح أيضاً ميزة تدريب السلسلة في #C. عندما يقوم برنامج بالتصريح عن اثنين أو أكثر من متغيرات السلاسل المتشابهة، يقوم المحول البرمجي بتخزينها في نفس الموقع. عن طريق استدعاء الأسلوب ReferenceEquals يمكنك مشاهدة أن كلاً من السلاسل فعلياً تشير إلى نفس الكائن في الذاكرة. استخدم الأسلوب String.Copy لتجنب ميزة التدريب، كما هو موضح في المثال.


// 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.");

يظهر المثال التالي كيفية مقارنة السلاسل بالطريقة المفضلة باستخدام الأساليب System.String التي تأخذ التعداد StringComparison. لاحظ أن أساليب المثيل String.CompareTo لا يتم استخدامها هنا، لأنه لا يأخذ أي أسلوب تم التحميل الزائد له 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.
 */

يظهر المثال التالي كيفية فرز والبحث عن السلاسل في صفيف بطريقة محسسة لثقافة باستخدام الأساليب الثابتة Array التي تأخذ المعلمة System.StringComparer.

    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.
     */

فئات المجموعات مثل System.Collections.Hashtable و System.Collections.Generic.Dictionary<TKey, TValue> و System.Collections.Generic.List<T> تحتوي على دوال إنشائية تأخذ معلمة System.StringComparer عندما يكون نوع العناصر أو المفاتيح string. بشكل عام، يجب استخدام هذه الدوال الإنشائية قدر الإمكان، وتعيين إما Ordinal أو OrdinalIgnoreCase.

راجع أيضًا:

المرجع

السلاسل (البرمجة C# إرشادات)

System.Globalization.CultureInfo

System.StringComparer

المبادئ

مقارنة سلاسل

موارد أخرى

globalizing و الترجمة تطبيقات