question

Bob-7090 avatar image
0 Votes"
Bob-7090 asked Bob-7090 answered

Inconsistent behavior of C# CompareTo()

I'm writing a sorting algorithm in C#. The algorithm is written in one project (call it the "Sort project"). I've built another project (call it the "Scratch project") to use as a baseline to compare the results of CompareTo(). I get different results with the CompareTo() method in one project than I get in the other project. For example, "'1".CompareTo("0 ") gives a 1 in the Sort project but a -1 in the Scratch project. "-".CompareTo(" ") gives a -1 in the Sort project but a 1 in the Scratch project. "-".CompareTo("0") actually returns a 0 in the Sort project but a -1 in the Scratch project. The list goes on. However, for comparisons of completely numeric (1-9) and alphabetical (a-z,A-Z) characters seems to give the same results in both projects. I'm not aware of any culture specific settings, languages, or anything unusual in use in either of my projects. I'll include some screenshots but I can include more. I'm using Visual Studio Community 2022 (17.3.3) with .NET 4.8.04161.

Example 01 in Scratch project
Example 01 in Sort project


dotnet-csharpdotnet-runtimevs-debuggingvs-testing
example01-scratch.png (208.4 KiB)
example01-sort.png (239.4 KiB)
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @Bob-7090 ,
Welcome to Microsoft Q&A.

For example, "'1".CompareTo("0 ") gives a 1 in the Sort project but a -1 in the Scratch project.

From the screenshots you provided, "'1".CompareTo("0 ") returns 1 and "abby".CompareTo("abraham") returns -1.
There is no information shows "'1".CompareTo("0 ") returns -1.
Could you please provide more information about that?
0 Votes 0 ·
Bob-7090 avatar image Bob-7090 JiachenLiMFST-9349 ·

In example01-scratch.png, the two strings are compared on line 7 and the debugger is stopped on line 9. In example01-sort.png, the two strings are compared on line 24 and the debugger is stopped on line 26. The strings I'm referring to are "'1" and "0 ".

0 Votes 0 ·

I found another case that's really bizarre. In this case I get the same results across both projects. However the results are unexpected. Two short strings are compared, "a-ha" and "A-Ha". Lower case "a-ha" is sorted before upper case "A-Ha". However if you sort the full titles of those DVD's whose names start with those exact same strings, they sort differently. Notice the arrows in the screenshot. The green arrow is sorted before the blue arrow. The order is different, even though the strings start out the same way. There's still something else at play here that's messing with results. I'm going to guess that there's a difference between .NET in the two versions that are causing different results between the projects (examples 1 and 2), and that there's yet another sort setting that I'm missing that's causing "a-ha" and "A-Ha" to be sorted inconsistently (example 3).

example03.png

0 Votes 0 ·
example03.png (265.7 KiB)

Hi @Bob-7090 ,
Please check the following link to see if it helps.
https://learn.microsoft.com/en-us/dotnet/api/system.globalization.compareoptions?view=net-7.0#remarks
If you still have problems, please post the problem on github issue.


0 Votes 0 ·
Viorel-1 avatar image
0 Votes"
Viorel-1 answered Bob-7090 commented

It seems that you are using .NET 6 or Core in the first case, which performs a "String sort" (https://learn.microsoft.com/en-us/dotnet/api/system.globalization.compareoptions).

To obtain the same results in both of environments, try this comparison:

string.Compare( test1, test2, CultureInfo.CurrentCulture, CompareOptions.StringSort )

or use the appropriate values for CultureInfo and CompareOptions.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

The Sort project is targeting .NET Framework 4.8 and the Scratch project is targeting .NET 6.0. I attempted to compile the Sort project against .NET 6.0 but it does not appear in the target framework dropdown list in the project settings. All I have are .NET Framework (2.0, 3.0, 3.5, 4.7.2, and 4.8). The Scratch project has options for .NET (5.0, 6.0) and .NET Core (1.0, 1.1, 2.0, 2.1, 2.2, 3.0, 3.1).

I ran some more tests using your updated string compare syntax (see example02, attached). The third test is notable as it gives the same result within the project whether I use the updated string compare syntax or the original syntax. However between projects it gives different results.

example02-scratch.png
example02-sort.png


0 Votes 0 ·
example02-scratch.png (279.1 KiB)
example02-sort.png (265.9 KiB)
Bob-7090 avatar image
0 Votes"
Bob-7090 answered

I think you're right--I was just coming to the same conclusion. I think I want to be using CompareOptions.Ordinal in my specific circumstance. I'm using Compare() to sort items in a list. With the ordinal sort my compares have been consistent.

The comparison call that worked for me was
if (String.Compare(stringOne, stringTwo, CultureInfo.CurrentCulture, CompareOptions.Ordinal) <= 0) { // do things }

Thanks for your help everyone!

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.