Search code examples
c#stringcompareequals-operator

C# String.Equals returns false on identical strings


I am working on a project and for a part of it I need to compare 2 strings. My issue comes that whenever I try to compare them I always get false (==, .Equals(), String.Equals() - they all return false, even though I have 2 completely identical strings)

Here is a part of my code.

var tagType = JObject.Parse(json).First.First.ToString();
foreach (var type in assembly.ExportedTypes)
{
    var name = tagType;
    var currentType = type.Name;

    var a = name.Length;
    var b = currentType.Length;

    var result = currentType == name;
    var result1 = currentType.Equals(name);
    var result2 = String.Equals(name, currentType, StringComparison.CurrentCulture);
    var result3 = String.Equals(name, currentType, StringComparison.InvariantCulture);
    var result4 = String.Equals(name, currentType, StringComparison.Ordinal);
    var result5 = String.Equals(name, currentType, StringComparison.CurrentCultureIgnoreCase);
}

Now when debugging my foreach, I eventually reach a point where name and currentType both equal the same string - "AutoIncrementTag". At that same point their lengths (a and b) are equal - 16 characters.

This is what the debug output looks like:

//name -        "AutoIncrementТаg"
//currentType - "AutoIncrementTag"

//a - 16
//b - 16

// result - false
// result1 - false
// result2 - false
// result3 - false
// result4 - false
// result5 - false

And ALL of the comparisons below return false.

I even tried creating a new string out of both "name" and currenType. And nothing.

I am really stuck here. How can two identical strings (same length, so no hidden characters) return false with any kind of comparison.


Solution

  • The second last and third last characters are not the same.

    One of the second last characters is http://www.fileformat.info/info/unicode/char/0061/index.htm and the other is http://www.fileformat.info/info/unicode/char/0430/index.htm . They look the same, but aren't actually the same.

    To see it, run this program:

    using System;
    
    namespace ConsoleApplication4
    {
        class Program
        {
            static string GetEscapeSequence(char c)
            {
                return "\\u" + ((int)c).ToString("X4");
            }
    
            static void Main(string[] args)
            {
                var name = "AutoIncrementТаg";
                var currentType = "AutoIncrementTag";
    
                foreach (var character in name)
                {
                    Console.WriteLine(GetEscapeSequence(character));
                }
    
                Console.WriteLine("second string");
                foreach (var character in currentType)
                {
                    Console.WriteLine(GetEscapeSequence(character));
                }
    
                Console.ReadLine();
            }
        }
    }