Following is the code snippet from a console application -
class MyClass
{
public int GetDay(string data22)
{
int returnValue = 0;
There is an "invisible" character at the beginning of your
string ExecutionDay = "THURSDAY";
and it is the LEFT-TO-RIGHT MARK. You can check it with:
int len = ExecutionDay.Length; // 9 instead of 8
and
char ch = ExecutionDay[0]; // 8206
The ExecutionDay
string contains invisible characters, otherwise all checks would be true
The following lines return a different length, 9 and 8 respectively
Console.WriteLine(ExecutionDay.Length);
Console.WriteLine("THURSDAY".Length);
In short CompareTo is culture dependent. For example ß (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"));
Would print out
ß Compare ss 1: True
ß Compare ss 2: False
ß equals ss: False
ß == ss: False
In your case you have string that look the same, but are different. Usally I find it helpful to see the difference, this can be done with:
Console.WriteLine(
string.Join(", ",
ExecutionDay
.ToCharArray()
.Select(o =((int)o).ToString(CultureInfo.InvariantCulture))
.AsEnumerable()
)
);
resulting in character number code list:
8206, 84, 72, 85, 82, 83, 68, 65, 89
Where character 8206
in unicode is left-to-right mark
.
This will compare values ONLY IF it is a value type or primitive. Other then that it is and should be used as REFERENCE comparison. In C#, type string is special and both of 2 following assertions would yield to true:
string ss = getinput();//"SS"
assertTrue("SS"=="SS");
assertTrue( ss =="SS");
In Java however first will return true beacuse JIT runtime optimizer that collects all unique strings from code and creates a table that is used. Second one false, as string is just immutable character array and if entered by user a new memory space is used thus reference comparison returns false.
C# Guidelines for Implementing Equals and the Equality Operator (==)
Unlike == Equals method is just a virtual one defined in System.Object, and overridden by whichever classes choose to do so. Therefor the overridden version will be used and in case of string type this means contents comparison will be done.
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.
This method performs a word (case-sensitive and culture-sensitive) comparison using the current culture. For more information about word, string, and ordinal sorts, see System.Globalization.CompareOptions.
Source : Manual
Why does the first comparison (string.compare) work and the other two comparison methods does not work in THIS PARTICULAR CASE
There are invisible characters (particularly, a Left-to-Right mark (Thanks @MatthewWatson)) in your code. You can view them with any hex editor:
This is over-looked by string.Compare
, while it isn't with string.Equals
. You can see it in 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.