String.Equals 对比 String.Compare 对比“==”在行动中。需要解释
String.Equals vs String.Compare vs "==" in Action. Explanation needed
以下是来自控制台应用程序的代码片段 -
class MyClass
{
public int GetDay(string data22)
{
int returnValue = 0;
if (string.Compare(data22,"THURSDAY") == 0) // true
{
returnValue = (int)DayOfWeek.Thursday;
}
if (data22 == "THURSDAY") //false
{
returnValue = (int)DayOfWeek.Thursday;
}
if (string.Equals(data22, "THURSDAY"))//false
{
returnValue = (int)DayOfWeek.Thursday;
}
return returnValue;
}
}
class Program
{
static void Main(string[] args)
{
string ExecutionDay = "THURSDAY";
MyClass obj1 = new MyClass();
int MyDays = obj1.GetDay(ExecutionDay);
}
}
问题是 - 为什么第一个比较 (string.compare) 有效而其他两种比较方法在这个特殊情况下不起作用?
Why does the first comparison (string.compare) work and the other two
comparison methods does not work in THIS PARTICULAR CASE
您的代码中存在不可见字符(特别是 Left-to-Right mark(感谢@MatthewWatson))。您可以使用任何十六进制编辑器查看它们:
string.Compare
忽略了这一点,而 string.Equals
却没有。您可以在 the docs:
中看到它
Notes to Callers:
Character sets include ignorable characters. The
Compare(String, String) method does not consider such characters when
it performs a culture-sensitive comparison. For example, if the
following code is run on the .NET Framework 4 or later, a
culture-sensitive comparison of "animal" with "ani-mal" (using a soft
hyphen, or U+00AD) indicates that the two strings are equivalent.
ExecutionDay
字符串包含不可见字符,否则所有检查都为真
下面几行return不同的长度,分别是9和8
Console.WriteLine(ExecutionDay.Length);
Console.WriteLine("THURSDAY".Length);
您的
开头有一个"invisible"字符
string ExecutionDay = "THURSDAY";
而且是LEFT-TO-RIGHT MARK。您可以通过以下方式查看:
int len = ExecutionDay.Length; // 9 instead of 8
和
char ch = ExecutionDay[0]; // 8206
简而言之,CompareTo 依赖于文化。例如 ß (s sharp from German):
Console.WriteLine("ß Compare ss 1: " + ("ß".CompareTo("ss") == 0));
Console.WriteLine("ß Compare ss 2: " + (String.Compare("ß", "ss", StringComparison.Ordinal) == 0));
Console.WriteLine("ß equals ss: " + "ß".Equals("ss"));
Console.WriteLine("ß == ss: " + ("ß" == "ss"));
会打印出来
ß Compare ss 1: True
ß Compare ss 2: False
ß equals ss: False
ß == ss: False
在您的情况下,您的字符串看起来相同,但有所不同。通常我发现查看差异很有帮助,这可以通过以下方式完成:
Console.WriteLine(
string.Join(", ",
ExecutionDay
.ToCharArray()
.Select(o =((int)o).ToString(CultureInfo.InvariantCulture))
.AsEnumerable()
)
);
导致字符编号代码列表:
8206, 84, 72, 85, 82, 83, 68, 65, 89
其中字符 8206
在 unicode 中是 left-to-right mark
.
==比较
只有当它是值类型或基元时,它才会比较值。除此之外,它是并且应该用作参考比较。在 C# 中,字符串类型是特殊的,以下两个断言都会产生 true:
string ss = getinput();//"SS"
assertTrue("SS"=="SS");
assertTrue( ss =="SS");
然而,在 Java 中,首先会 return 为真,因为 JIT 运行时优化器会从代码中收集所有唯一的字符串并创建一个要使用的 table。第二个错误,因为字符串只是 immutable 字符数组,如果用户输入新内存 space 则使用参考比较 returns false.
C# Guidelines for Implementing Equals and the Equality Operator (==)
等于比较
与 == 不同,Equals 方法只是在 System.Object 中定义的一个虚拟方法,并且会被任何 类 选择这样做的方法覆盖。因此将使用覆盖版本,如果是字符串类型,这意味着将进行内容比较。
Follow these guidelines when overriding Equals(Object):
- Types that implement IComparable must override Equals(Object).
- Types that override Equals(Object) must also override GetHashCode; otherwise, hash tables might not work correctly.
- You should consider implementing the IEquatable interface to support strongly typed tests for equality. Your IEquatable.Equals
implementation should return results that are consistent with Equals.
- If your programming language supports operator overloading and you overload the equality operator for a given type, you must also
override the Equals(Object) method to return the same result as the
equality operator. This helps ensure that class library code that uses
Equals (such as ArrayList and Hashtable) behaves in a manner that is
consistent with the way the equality operator is used by applicat
C# Implementing the Equals Method
比较比较
Caution
The CompareTo method was designed primarily for
use in sorting or alphabetizing operations. It should not be used when
the primary purpose of the method call is to determine whether two
strings are equivalent. To determine whether two strings are
equivalent, call the Equals method.
此方法使用当前区域性执行单词(区分大小写和区域性)比较。有关单词、字符串和序数排序的详细信息,请参阅 System.Globalization.CompareOptions。
来源:Manual
以下是来自控制台应用程序的代码片段 -
class MyClass
{
public int GetDay(string data22)
{
int returnValue = 0;
if (string.Compare(data22,"THURSDAY") == 0) // true
{
returnValue = (int)DayOfWeek.Thursday;
}
if (data22 == "THURSDAY") //false
{
returnValue = (int)DayOfWeek.Thursday;
}
if (string.Equals(data22, "THURSDAY"))//false
{
returnValue = (int)DayOfWeek.Thursday;
}
return returnValue;
}
}
class Program
{
static void Main(string[] args)
{
string ExecutionDay = "THURSDAY";
MyClass obj1 = new MyClass();
int MyDays = obj1.GetDay(ExecutionDay);
}
}
问题是 - 为什么第一个比较 (string.compare) 有效而其他两种比较方法在这个特殊情况下不起作用?
Why does the first comparison (string.compare) work and the other two comparison methods does not work in THIS PARTICULAR CASE
您的代码中存在不可见字符(特别是 Left-to-Right mark(感谢@MatthewWatson))。您可以使用任何十六进制编辑器查看它们:
string.Compare
忽略了这一点,而 string.Equals
却没有。您可以在 the docs:
Notes to Callers:
Character sets include ignorable characters. The Compare(String, String) method does not consider such characters when it performs a culture-sensitive comparison. For example, if the following code is run on the .NET Framework 4 or later, a culture-sensitive comparison of "animal" with "ani-mal" (using a soft hyphen, or U+00AD) indicates that the two strings are equivalent.
ExecutionDay
字符串包含不可见字符,否则所有检查都为真
下面几行return不同的长度,分别是9和8
Console.WriteLine(ExecutionDay.Length);
Console.WriteLine("THURSDAY".Length);
您的
开头有一个"invisible"字符string ExecutionDay = "THURSDAY";
而且是LEFT-TO-RIGHT MARK。您可以通过以下方式查看:
int len = ExecutionDay.Length; // 9 instead of 8
和
char ch = ExecutionDay[0]; // 8206
简而言之,CompareTo 依赖于文化。例如 ß (s sharp from German):
Console.WriteLine("ß Compare ss 1: " + ("ß".CompareTo("ss") == 0));
Console.WriteLine("ß Compare ss 2: " + (String.Compare("ß", "ss", StringComparison.Ordinal) == 0));
Console.WriteLine("ß equals ss: " + "ß".Equals("ss"));
Console.WriteLine("ß == ss: " + ("ß" == "ss"));
会打印出来
ß Compare ss 1: True
ß Compare ss 2: False
ß equals ss: False
ß == ss: False
在您的情况下,您的字符串看起来相同,但有所不同。通常我发现查看差异很有帮助,这可以通过以下方式完成:
Console.WriteLine(
string.Join(", ",
ExecutionDay
.ToCharArray()
.Select(o =((int)o).ToString(CultureInfo.InvariantCulture))
.AsEnumerable()
)
);
导致字符编号代码列表:
8206, 84, 72, 85, 82, 83, 68, 65, 89
其中字符 8206
在 unicode 中是 left-to-right mark
.
==比较
只有当它是值类型或基元时,它才会比较值。除此之外,它是并且应该用作参考比较。在 C# 中,字符串类型是特殊的,以下两个断言都会产生 true:
string ss = getinput();//"SS"
assertTrue("SS"=="SS");
assertTrue( ss =="SS");
然而,在 Java 中,首先会 return 为真,因为 JIT 运行时优化器会从代码中收集所有唯一的字符串并创建一个要使用的 table。第二个错误,因为字符串只是 immutable 字符数组,如果用户输入新内存 space 则使用参考比较 returns false.
C# Guidelines for Implementing Equals and the Equality Operator (==)
等于比较
与 == 不同,Equals 方法只是在 System.Object 中定义的一个虚拟方法,并且会被任何 类 选择这样做的方法覆盖。因此将使用覆盖版本,如果是字符串类型,这意味着将进行内容比较。
Follow these guidelines when overriding Equals(Object):
- Types that implement IComparable must override Equals(Object).
- Types that override Equals(Object) must also override GetHashCode; otherwise, hash tables might not work correctly.
- You should consider implementing the IEquatable interface to support strongly typed tests for equality. Your IEquatable.Equals implementation should return results that are consistent with Equals.
- If your programming language supports operator overloading and you overload the equality operator for a given type, you must also override the Equals(Object) method to return the same result as the equality operator. This helps ensure that class library code that uses Equals (such as ArrayList and Hashtable) behaves in a manner that is consistent with the way the equality operator is used by applicat
C# Implementing the Equals Method
比较比较
Caution
The CompareTo method was designed primarily for use in sorting or alphabetizing operations. It should not be used when the primary purpose of the method call is to determine whether two strings are equivalent. To determine whether two strings are equivalent, call the Equals method.
此方法使用当前区域性执行单词(区分大小写和区域性)比较。有关单词、字符串和序数排序的详细信息,请参阅 System.Globalization.CompareOptions。
来源:Manual