6

I have a C# function that accepts an array of IComparable

public static void sort(IComparable[] a){//...}

If I send an array of strings to this function it is accepted, but an array of ints is not accepted even though the structure Int32 extends IComparable.

public struct Int32 : IComparable, IFormattable, 
IConvertible, IComparable<int>, IEquatable<int>

First question is why it is not possible to send an array of value type to such a function.

Second question is how should I send the array of value type to the function that accepts array of IComparable.

Horea
  • 75
  • 4

1 Answers1

9

Although an int is an IComparable, an int[] isn't an IComparable[]. Imagine if it were:

int[] x = new int[10];
IComparable[] y = x;
y[0] = "hello";

That would be trying to store a reference in an int[]. Badness.

Basically, value-type arrays aren't covariant. (Reference type arrays are covariant at compile-time, but will throw if you try to store an invalid value at execution time. That's a design flaw IMO, but never mind...)

The way to fix this is to use generics:

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

Or even better use the generic form of IComparable:

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

(That way you'll avoid boxing when you call CompareTo.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • @PetSerAl: That fails for a different reason though - it's still an array of references, it's just that it knows it would be incompatible at execution time. It's not clear what you mean by "you can not even read reference from value-type array" - you can't *store* a reference (at all) in a value-type array... – Jon Skeet Jan 29 '15 at 15:35
  • @PetSerAl: If it didn't throw an exception, it would make sense for it to refer to a boxed `int`, just like `IComparable c = x[0];` would. That feels much more sane to me than trying to store a reference in a value type array... – Jon Skeet Jan 29 '15 at 15:42
  • @PetSerAl: Unboxing is always explicit; boxing isn't. I suggest that if you feel you can write a clearer answer, you do so - I'm finding it hard to understand your point here, and comments aren't really a good way of debating this. – Jon Skeet Jan 29 '15 at 16:20