>>44987> Я, честно говоря, не знаю шарп, просто проходил мимо.
Если ты не
>>44983-кун, то прошу прощения, я тебя с ним перепутал.
> Тут же как-то делается полиморфнная коллекция?
Именно так,
IRectangle[] будет такой полиморфной коллекцией. В неё можно положить
Rectangle,
DummyRectangle,
Win32Rectangle и ещё кучу всяких реализаций
IRectangle, которые ты напишешь. Однако храниться они будут как ссылки на
IRectangle, и без явного приведения к более конкретному типу ты не сможешь получить ссылку ссылку на
Rectangle.
Странно, конечно, что компилятор допускает присвоение вида
IRectangle[] arr = new Rectangle[]. Возможно, я ошибаюсь, и причина не в несовместимости типов
IRectangle[] и
Rectangle[], а в том, как компилятор вывел тип элементов массива при замене элементов. В методе
void Swap<T>(ref T, ref T) он полагал, что в массиве лежат переменные типа
IRectangle (т.к. именно этот тип был указан при создании экземпляра класса
Sorter), но... чисто технически, при замене без метода
Swap, массив
ar тоже должен был быть составлен из
IRectangle, поэтому переменная
a тоже должна была иметь тип
IRectangle. Не знаю, в общем.
Энивей, вот упрощённый пример:
http://ideone.com/9cWsEu Предлагаю форкнуть его и поиграться с типом переменной под массив и самого массива в строке 38. Легко убедиться, что если тип переменной
array и присвоенного ей массива совпадёт, то ошибка при вызове метода
DoFaultySwap() исчезнет.
>>44988> в фориче скорее неправильный тип, так? Там должно было быть IRectangle вместо конкретики.
Технически - да, это так. Однако C# позволяет указывать более конкретный тип в foreach - в этом случае компилятор сам попытается выполнить преобразование к указанному типу. Если очередной элемент массива
IRectangle не будет являться типом
Rectangle или его производной, будет сгенерировано исключение
InvalidCastException. Однако в коде из
>>44983 оно не возникнет, поскольку по факту в массиве лежат именно объекты типа
Rectangle, и поэтому приведение элементов массива к типу
Rectangle пройдёт успешно.