Передача коллекции интерфейса - PullRequest
5 голосов
/ 28 января 2010

Предположим, у вас есть следующий класс:

class Car : IPainting
{
 ...
}

Тогда такая функция:

void AddCars(IEnumerable<Car> collection)

Затем такой фрагмент кода:

Car bmw = new Car();
Car mercedes = new Car();

IPainting a = (IPainting) bmw;
IPainting b = (IPainting) mercedes;

IPainting[] paintings = new IPainting[] {a, b};

AddCars(paintings); // fails to compile

Это, конечно, не компилируется, потому что метод AddCars () принимает только коллекцию Cars, но это то, из чего состоит массив 'painting'.

Я знаю, что C # 4.0, вероятно, предоставит решение для этого. Есть ли обходной путь сегодня?

Спасибо

Альберто

Ответы [ 4 ]

8 голосов
/ 28 января 2010

Попробуйте использовать универсальный метод:

void AddCars<T>(IEnumerable<T> collection) where T : IPainting
4 голосов
/ 28 января 2010

Ваш код в корне ошибочный. Ваш класс гарантирует, что все автомобили используют IPainting, но нет гарантии, что все IPainting - это автомобили.

Скорее всего, вы могли бы сделать эту работу с некоторыми кастингами, но я думаю, вам следует пересмотреть свой дизайн.

AddCars(new Car[] { bmw, mercedes });
4 голосов
/ 28 января 2010

Как насчет использования Linq: AddCars(paintings.Cast<Car>());

3 голосов
/ 28 января 2010

C # 4 не разрешит код, который вы написали, так как метод AddCars ожидает IEnumerable<Car>, который реализует IPainting. Это не означает, что вы можете передать любой класс , реализующий IPainting (например, вы можете иметь class Bike : IPainting, который не имеет никакого отношения к классу Car. Однако, это позволит другим наоборот, если у вас есть void AddCars(IEnumerable<IPainting> collection), вы можете передать List<Car> методу.

До этого вам нужно будет передавать в метод Car последовательности, используя некоторый механизм приведения (такой как painting.Cast<Car>(), предложенный в других ответах).

...