StringComparison.OrdinalIgnoreCaseの戻り値はどうあるべきですか?
以下の行を実行すると
returnVal=string.Compare("stringOne","stringTwo",StringComparison.OrdinalIgnoreCase);
returnValを-5として取得します。なぜそんなことなのか説明してもらえますか?また、他の文字列値では、13,15などの戻り値を取得します。通常は-1,0,1である必要があります。私が間違っていなければ。
回答
「通常は-1,0,1である必要があります。私が間違っていなければ」
これらは通常、Compareメソッドの戻り値であり、次のドキュメントでも推奨される方法であることが正しいですIComparer.Compare。
https://docs.microsoft.com/en-us/troubleshoot/dotnet/csharp/use-icomparable-icomparer
「
IComparer.Compare方法は、第三の比較を必要とする1、0または-1他の以下に等しい、または、一つの値がより大きいか否かに応じて返される。ソート順(昇順または降順)をこの方法で論理演算子を切り替えることにより変更することができます。」
ただし、これはどこにも適用されません。
また、Stringクラスはを実装せずIComparer<string>、Compare署名のこのオーバーロードはとにかくそのインターフェイスで定義されていません。
ここでCompareメソッドのソースコードを見ると、の場合、メソッドが呼び出され、一致しない文字の最初のペア間のASCII値の差が返されます(大文字にした後)。文字列の長さが異なるが、長い方の最初の文字がすべて短い方の文字と一致する場合、長さの差が返されます。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;
}
}
したがって、我々は常に結果を比較すべきであるCompareと方法を0していません-1か1。