Skyglar
Skyglar

Reputation: 145

Primitives and IComparable interface

In Java if I wanna sort any data independent to its data type I would use Comparable interface and I found out we have similar interface in C#, so I have simple sorting algorithm:

public static void Sort(IComparable[] arr)
{
    bool swap = true;
    while (swap)
    {
        swap = false;
        for (int i = 0; i < arr.Length - 1; i++)
        {
            if (Less(arr[i + 1], arr[i]))
            {
                Exchange(arr, i, i + 1);
                swap = true;
            }
        }
    }
} 

So I can sort any objects that implements IComparable interface, but I can't sort any primitive datatypes and as I know C# doesn't have wrapper types for primitives like int -> Integer, but it has some structures like Int32 that actually implements IComparable interface but I still can't use it for some reason, for example:

static void Main(string[] args)
{
    Int32[] ints = { 5, 2, 9, 0, 3};
    BubbleSort.Sort(ints);

    ReadKey();
}

I will get an error:

Error   CS1503  Argument 1: cannot convert from 'int[]' to 'System.IComparable[]'

But if we check out metadata of Int32 we can see it implements IComparable

code

So,

  1. What I don't know?
  2. What's wrong here?
  3. How can I make it better to sort any data?

Upvotes: -2

Views: 350

Answers (2)

Skyglar
Skyglar

Reputation: 145

If someone was interested:

public static class BubbleSort<T>
{
        public static void Sort(T[] arr, Comparer<T> comparer = null)
        {
            Comparer<T> equaltyComparer = comparer ?? Comparer<T>.Default;

            bool swap = true;
            while (swap)
            {
                swap = false;
                for (int i = 0; i < arr.Length - 1; i++)
                {
                    if (Less(equaltyComparer, arr[i + 1], arr[i]))
                    {
                        Exchange(arr, i, i + 1);
                        swap = true;
                    }
                }
            }
        }
        
        private static bool Less(Comparer<T> comparer, T v, T w)
        {
            return  comparer.Compare(v, w) < 0;
        }

        private static void Exchange(T[] arr, int i, int j)
        {
            T temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
}

Upvotes: -1

Jon Skeet
Jon Skeet

Reputation: 1499770

An int[] isn't an IComparable[] - the latter is an array of references.

But there's a simple solution, which will also avoid boxing. Change your method declaration to be generic with a constraint on the type parameter:

public static void Sort<T>(IComparable<T>[] arr) where T : IComparable<T>

You may need to change your Exchange and Less methods as well - you haven't told us what that looks like. But they could (and probably should) be generic too. The method body of Sort shouldn't need to change, at that point.

Upvotes: 3

Related Questions