xamarin / xamarin-macios

.NET for iOS, Mac Catalyst, macOS, and tvOS provide open-source bindings of the Apple SDKs for use with .NET managed languages such as C#
Other
2.46k stars 511 forks source link

NSString does not implement IComparable<T> #5522

Closed Therzok closed 4 years ago

Therzok commented 5 years ago

Steps to Reproduce

NSString[] array = {
    (NSString)"c",
    (NSString)"a",
    (NSString)"b",
};

Array.Sort(array);

foreach (var val in array)
    Console.WriteLine(val);

Expected Behavior

NSString should implement IComparable and the result output should be:

a
b
c

Actual Behavior

System.InvalidOperationException: Failed to compare two elements in the array. ---> System.ArgumentException: At least one object must implement IComparable.
  at System.Collections.Comparer.Compare (System.Object a, System.Object b) [0x00057] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.6.0.2/src/Xamarin.Mac/external/corefx/src/Common/src/CoreLib/System/Collections/Comparer.cs:76
  at System.Collections.Generic.ObjectComparer`1[T].Compare (T x, T y) [0x00000] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.6.0.2/src/Xamarin.Mac/mcs/class/referencesource/mscorlib/system/collections/generic/comparer.cs:150
  at System.Collections.Generic.ArraySortHelper`1[T].SwapIfGreater (T[] keys, System.Comparison`1[T] comparer, System.Int32 a, System.Int32 b) [0x00004] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.6.0.2/src/Xamarin.Mac/external/corert/src/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs:137
  at System.Collections.Generic.ArraySortHelper`1[T].IntroSort (T[] keys, System.Int32 lo, System.Int32 hi, System.Int32 depthLimit, System.Comparison`1[T] comparer) [0x00028] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.6.0.2/src/Xamarin.Mac/external/corert/src/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs:194
  at System.Collections.Generic.ArraySortHelper`1[T].IntrospectiveSort (T[] keys, System.Int32 left, System.Int32 length, System.Comparison`1[T] comparer) [0x00005] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.6.0.2/src/Xamarin.Mac/external/corert/src/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs:168
  at System.Collections.Generic.ArraySortHelper`1[T].Sort (T[] keys, System.Int32 index, System.Int32 length, System.Collections.Generic.IComparer`1[T] comparer) [0x0000a] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.6.0.2/src/Xamarin.Mac/external/corert/src/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs:55
  --- End of inner exception stack trace ---
  at System.Collections.Generic.ArraySortHelper`1[T].Sort (T[] keys, System.Int32 index, System.Int32 length, System.Collections.Generic.IComparer`1[T] comparer) [0x0002b] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.6.0.2/src/Xamarin.Mac/external/corert/src/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs:63
  at System.Array.Sort[T] (T[] array, System.Int32 index, System.Int32 length, System.Collections.Generic.IComparer`1[T] comparer) [0x00048] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.6.0.2/src/Xamarin.Mac/external/corert/src/System.Private.CoreLib/src/System/Array.cs:1097
  at System.Array.Sort[T] (T[] array) [0x0000e] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.6.0.2/src/Xamarin.Mac/external/corert/src/System.Private.CoreLib/src/System/Array.cs:1072
  at testcreatemac.AppDelegate.DidFinishLaunching (Foundation.NSNotification notification) [0x0002f] in /Users/therzok/Projects/testcreatemac/AppDelegate.cs:24
  at at (wrapper managed-to-native) AppKit.NSApplication.NSApplicationMain(int,string[])
  at AppKit.NSApplication.Main (System.String[] args) [0x00040] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.6.0.2/src/Xamarin.Mac/AppKit/NSApplication.cs:100
  at testcreatemac.MainClass.Main (System.String[] args) [0x00007] in /Users/therzok/Projects/testcreatemac/Main.cs:10

Environment

Xamarin.Mac Version: 5.6.0.2 (Visual Studio Enterprise) Hash: 040682909 Branch: d16-0 Build date: 2018-12-14 06:23:20-0500

Example Project (If Possible)

See code above, not sure it needs a project.

Workaround

It's possible to pass a custom IComparer, but should not be needed.

Therzok commented 5 years ago

Possible fix:

class NSString : IComparer<T>
{
    public int CompareTo (NSString other)
    {
        return (int)Compare(other);
    }
}
Therzok commented 5 years ago

Possibly applies to NSAttributedString/NSMutableAttributedString.

Therzok commented 4 years ago

I've opened a PR for this. NSAttributedString and NSMutableAttributedString don't support comparison.