How to send an array of ints to a function that accepts array of IComparable?
Asked Answered
T

1

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.

Thorbert answered 29/1, 2015 at 15:17 Comment(0)
F
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.)

Foulness answered 29/1, 2015 at 15:21 Comment(3)
@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...Foulness
@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...Foulness
@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.Foulness

© 2022 - 2024 — McMap. All rights reserved.