Общая коллекция столкновений - PullRequest
0 голосов
/ 09 февраля 2012

Вот моя лучшая попытка воссоздать ситуацию.

public interface IFoo
{

}

public class Foo : IFoo { }

public class Bar : IFoo { }

public class CollectionOf<T> : List<IFoo>
{

}

public class Bars : CollectionOf<Bar>
{

}

public class Test
{
    public void Test()
    {
        CollectionOf<IFoo> bars = new Bars();
    }
}

Компилятор жалуется на создание экземпляра.Бары это коллекция IFoos.Это одна из тех проблем ковариации / контравариантности?

Ответы [ 3 ]

4 голосов
/ 09 февраля 2012

Да.

Подумайте об этом на секунду;bars должен по закону иметь возможность хранить объекты любого типа, которые реализуют IFoo.Однако объект типа Bars может только содержать объекты типа Bar.

Используя ваш код, это будет разрешено, что, очевидно, неправильно.

CollectionOf<IFoo> bars = new Bars();
bars.Add( new Foo() );  // Uh oh!

Это фактически нарушит безопасность типов, предоставляемую вам с помощью обобщений.

2 голосов
/ 09 февраля 2012

Да, это так.

Если бы это было разрешено, вы могли бы поместить любой объект в эту коллекцию, если он реализовал интерфейс IFoo, но это не было бы безопасно для коллекции.

Позвольте мне проиллюстрировать:

var b = new Bars();
CollectionOf<IFoo> bars = b;
bars.Add(Dummy); // implements IFoo, but does not descend from Bar

На данный момент, что содержит b? Объект типа Dummy? Это было бы плохо, и, следовательно, это недопустимо.

1 голос
/ 09 февраля 2012

Исправление, если оно есть, будет зависеть от того, что вам не подходит.Я могу заставить ваш пример компилироваться двумя способами: либо использовать IEnumerable, либо определить ваш CollectionOf как интерфейс с модификатором out generic.Является ли это решением для вас, я не знаю:

public interface IFoo { }

public class Foo : IFoo { }

public class Bar : IFoo { }

public interface CollectionOf<out T> : IEnumerable<IFoo> { }

public class Bars : CollectionOf<Bar> { }

public class Test
{
    public void Test()
    {
        IEnumerable<IFoo> bars1 = new Bars();
        CollectionOf<IFoo> bars2 = new Bars();
    }
}
...