>>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
пройдёт успешно.