String.Equals vs String.Compare vs “==” in Action. Explanation needed

前端 未结 4 976
半阙折子戏
半阙折子戏 2021-02-20 06:59

Following is the code snippet from a console application -

class MyClass
{        
   public int GetDay(string data22)
    {
        int returnValue = 0;

              


        
相关标签:
4条回答
  • 2021-02-20 07:35

    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
    
    0 讨论(0)
  • 2021-02-20 07:48

    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);
    
    0 讨论(0)
  • 2021-02-20 07:52

    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.


    == comparison

    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 (==)

    Equals comparison

    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

    ComparedTo comparison

    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

    0 讨论(0)
  • 2021-02-20 08:01

    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:

    enter image description here

    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.

    0 讨论(0)
提交回复
热议问题