StringComparison.OrdinalIgnoreCase 的 return 值应该是多少?
what should be the return value of StringComparison.OrdinalIgnoreCase?
当我执行以下行时
returnVal=string.Compare("stringOne","stringTwo",StringComparison.OrdinalIgnoreCase);
我得到 returnVal 为 -5。
谁能解释一下为什么会这样?还有其他字符串值,我得到 return 值为 13,15 等。
它通常应该是-1,0,1。如果我没记错的话
"It should usually be -1,0,1. If i am not wrong"
您是正确的,这些通常是 Compare
方法的 return 值,以及推荐的做法,即使在 IComparer.Compare
:
的文档中也是如此
https://docs.microsoft.com/en-us/troubleshoot/dotnet/csharp/use-icomparable-icomparer
"The IComparer.Compare
method requires a tertiary comparison. 1
, 0
, or -1
is returned depending on whether one value is greater than, equal to, or less than the other. The sort order (ascending or descending) can be changed by switching the logical operators in this method."
然而,这并没有在任何地方强制执行。
另外,String
class 没有实现 IComparer<string>
,并且 Compare
签名的这个重载无论如何都没有在那个接口中定义。
如果我们查看Compare
方法here, we see that for OrdinalIgnoreCase
, it calls the CompareOrdinalIgnoreCaseHelper
方法的源代码,其中return是第一对[=]之间的ascii值差异46=] 个字符(在 upper-casing 个字符之后)。如果字符串的长度不同,但较长的字符串的第一个字符都与较短的字符串的第一个字符匹配,则它们的长度差为 returned.
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
。
当我执行以下行时
returnVal=string.Compare("stringOne","stringTwo",StringComparison.OrdinalIgnoreCase);
我得到 returnVal 为 -5。 谁能解释一下为什么会这样?还有其他字符串值,我得到 return 值为 13,15 等。 它通常应该是-1,0,1。如果我没记错的话
"It should usually be -1,0,1. If i am not wrong"
您是正确的,这些通常是 Compare
方法的 return 值,以及推荐的做法,即使在 IComparer.Compare
:
https://docs.microsoft.com/en-us/troubleshoot/dotnet/csharp/use-icomparable-icomparer
"The
IComparer.Compare
method requires a tertiary comparison.1
,0
, or-1
is returned depending on whether one value is greater than, equal to, or less than the other. The sort order (ascending or descending) can be changed by switching the logical operators in this method."
然而,这并没有在任何地方强制执行。
另外,String
class 没有实现 IComparer<string>
,并且 Compare
签名的这个重载无论如何都没有在那个接口中定义。
如果我们查看Compare
方法here, we see that for OrdinalIgnoreCase
, it calls the CompareOrdinalIgnoreCaseHelper
方法的源代码,其中return是第一对[=]之间的ascii值差异46=] 个字符(在 upper-casing 个字符之后)。如果字符串的长度不同,但较长的字符串的第一个字符都与较短的字符串的第一个字符匹配,则它们的长度差为 returned.
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
。