StringComparison.OrdinalIgnoreCase'in dönüş değeri ne olmalıdır?

Aug 24 2020

Aşağıdaki satırı yürüttüğümde

returnVal=string.Compare("stringOne","stringTwo",StringComparison.OrdinalIgnoreCase);

ReturnVal değerini -5 olarak alıyorum. Biri bana neden böyle olduğunu açıklayabilir mi? Ve ayrıca diğer string değerlerinde dönüş değerini 13,15 vb. Olarak alırım. Genellikle -1,0,1 olmalıdır. Eğer yanılmıyorsam.

Yanıtlar

1 RufusL Aug 24 2020 at 21:38

"Genellikle -1,0,1 olmalıdır. Eğer yanılmıyorsam"

Bunların tipik olarak Compareyöntemin dönüş değerleri olduğu ve aşağıdakiler için belgelerde bile önerilen uygulama olduğu konusunda haklısınız IComparer.Compare:

https://docs.microsoft.com/en-us/troubleshoot/dotnet/csharp/use-icomparable-icomparer

" IComparer.CompareYöntemi. Üçüncül karşılaştırma gerektirir 1, 0ya da -1diğer daha küçük, ona eşit, ya da, bir değerinden daha büyük olup olmadığının bağlı olarak döndürülür. Sıralama düzeni (artan veya azalan) Bu yöntemde mantıksal operatörleri geçiş değiştirilebilir . "

Ancak bu hiçbir yerde uygulanmaz.

Ayrıca, Stringsınıf uygulama yapmaz IComparer<string>ve Compareimzanın bu aşırı yüklemesi zaten o arabirimde tanımlanmamıştır.

BuradakiCompare yöntemin kaynak koduna bakarsak , bunun için , ilk eşleşmeyen karakter çifti arasındaki ascii değeri farkını döndüren yöntemi çağırdığını görürüz (büyük harfle yazıldıktan sonra) . Dizeler farklı uzunluklarda ise ancak daha uzun olanın ilk karakterlerinin tümü daha kısa olanla eşleşiyorsa, uzunluklarındaki fark döndürülür.OrdinalIgnoreCaseCompareOrdinalIgnoreCaseHelper

private unsafe static int CompareOrdinalIgnoreCaseHelper(String strA, String strB)
{
    Contract.Requires(strA != null);
    Contract.Requires(strB != null);
    Contract.EndContractBlock();
    int length = Math.Min(strA.Length, strB.Length);

    fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
    {
        char* a = ap;
        char* b = bp;

        while (length != 0) 
        {
            int charA = *a;
            int charB = *b;

            Contract.Assert((charA | charB) <= 0x7F, "strings have to be ASCII");

            // uppercase both chars - notice that we need just one compare per char
            if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20;
            if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20;

            //Return the (case-insensitive) difference between them.
            if (charA != charB)
                return charA - charB;

            // Next char
            a++; b++;
            length--;
        }

        return strA.Length - strB.Length;
    }
}

Bu nedenle, her zaman bir Compareyöntemin sonucunu ya da 0değil ile karşılaştırmalıyız .-11