quale dovrebbe essere il valore di ritorno di StringComparison.OrdinalIgnoreCase?
Quando eseguo la riga sottostante
returnVal=string.Compare("stringOne","stringTwo",StringComparison.OrdinalIgnoreCase);
Ottengo il ritorno Val come -5. Qualcuno può spiegarmi perché è così? E anche con altri valori stringa ottengo il valore di ritorno come 13,15 ecc. Di solito dovrebbe essere -1,0,1. Se non sbaglio.
Risposte
"Di solito dovrebbe essere -1,0,1. Se non sbaglio"
Hai ragione sul fatto che questi sono in genere i valori di ritorno del Comparemetodo e la pratica consigliata, anche nella documentazione per IComparer.Compare:
https://docs.microsoft.com/en-us/troubleshoot/dotnet/csharp/use-icomparable-icomparer
"Il
IComparer.Comparemetodo richiede un confronto terziario.1,0O-1viene restituito a seconda che un valore sia maggiore, uguale o minore dell'altro. L'ordinamento (crescente o decrescente) può essere modificato cambiando gli operatori logici in questo metodo . "
Tuttavia, questo non viene applicato da nessuna parte.
Inoltre, la Stringclasse non implementa IComparer<string>e questo sovraccarico della Comparefirma non è comunque definito in quell'interfaccia.
Se guardiamo il codice sorgente per il Comparemetodo qui , vediamo che per OrdinalIgnoreCase, chiama il CompareOrdinalIgnoreCaseHelpermetodo, che restituisce la differenza di valore ASCII tra la prima coppia di caratteri non corrispondenti (dopo averli inseriti in maiuscolo) . Se le stringhe hanno lunghezze diverse ma i primi caratteri di quella più lunga corrispondono tutti a quelli di quella più corta, viene restituita la differenza nella loro lunghezza.
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;
}
}
Pertanto, dovremmo sempre confrontare il risultato di un Comparemetodo con 0e non -1o 1.