Как отправить массив целых чисел в функцию, которая принимает массив IComparable?

У меня есть функция С#, которая принимает массив IComparable

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

Если я отправлю этой функции массив строк, он будет принят, но массив целых чисел не будет принят, хотя структура Int32 расширяет IComparable.

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

Первый вопрос: почему в такую ​​функцию нельзя отправить массив типа значения.

Второй вопрос: как мне отправить массив типа значения в функцию, которая принимает массив IComparable.


person Horea    schedule 29.01.2015    source источник


Ответы (1)


Хотя int — это IComparable, int[] не является IComparable[]. Представьте, если бы это было:

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

Это будет попытка сохранить ссылку в файле int[]. Плохость.

По сути, массивы значений не являются ковариантными. (Массивы ссылочного типа являются ковариантными во время компиляции, но будут выброшены, если вы попытаетесь сохранить недопустимое значение во время выполнения. Это недостаток дизайна IMO, но неважно...)

Способ исправить это - использовать дженерики:

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

Или, что еще лучше, используйте общую форму IComparable:

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

(Таким образом, вы избежите бокса при вызове CompareTo.)

person Jon Skeet    schedule 29.01.2015
comment
@PetSerAl: это не удается по другой причине - это все еще массив ссылок, просто он знает, что он будет несовместим во время выполнения. Непонятно, что вы имеете в виду, когда не можете даже прочитать ссылку из массива значений - вы не можете сохранить ссылку (вообще) в массиве значений... - person Jon Skeet; 29.01.2015
comment
@PetSerAl: если бы он не выдавал исключение, для него имело бы смысл ссылаться на int в штучной упаковке, как это делал бы IComparable c = x[0];. Мне это кажется гораздо более разумным, чем попытка сохранить ссылку в массиве типов значений... - person Jon Skeet; 29.01.2015
comment
@PetSerAl: распаковка всегда явная; бокс - нет. Я предлагаю, если вы чувствуете, что можете написать более четкий ответ, сделайте это - мне трудно понять вашу точку зрения, и комментарии - не очень хороший способ обсудить это. - person Jon Skeet; 29.01.2015