Как сделать общий полиморфизм на открытых типах в C #? - PullRequest
3 голосов
/ 05 октября 2019

У меня есть интерфейс, подобный:

interface IFoo<in T> {
   ...
}

И я хочу иметь коллекцию этих классов БЕЗ , принудительно задающую определенный универсальный параметр для всех элементов коллекции, например:

class IFooCollection {
   List<IFoo<?>> _items;

   public IFooCollection(List<IFoo<?>> items)
   {
        _items = items;
   }

   ...
}

Ответы [ 2 ]

3 голосов
/ 05 октября 2019

Поскольку вы не хотите принудительно указывать определенный тип, создайте abstract class или interface следующим образом:

interface IFoo { }

и наследуйте его в специфичном для вашего типа Foo (с общими параметрами), например:

interface IFoo<T> : IFoo {}

Таким образом, вы можете просто получить List<IFoo> и добавить вместо него IFoo<T>.

Дополнительные примеры:

class FooCollection {
    private List<IFoo> _collection;

    public FooCollection()
    {
        _collection = new List<IFoo>();
    }

    public void Add(IFoo foo)
    {
        _collection.Add(foo);
    }

    public void Remove(IFoo foo)
    {
        _collection.Remove(foo);
    }
}
1 голос
/ 05 октября 2019

Как указано @IvMisticos, чтобы иметь возможность делать псевдобиоморфный полиморфизм для открытого типа, вы можете написать:

interface IFoo
{
}

interface IFoo<in T> : IFoo
{

}

class FooCollection 
{
  List<IFoo> _items;

  public FooCollection(List<IFoo> items)
  {
    _items = items;
  }
}

var item1 = some instance of IFoo<int>;
var item2 = some instance of IFoo<double>;
var item3 = some instance of IFoo<string>;

var list = new List<IFoo> { item1, item2, item3 };

var col = new FooCollection(list);

Поскольку отсутствует оператор ромба <>, разрешающий истинный универсальный полиморфизм при открытомтипы в C #, это единственное, что вы можете сделать, насколько я знаю.

Мне очень не нравится этот хак, который плохо пахнет.

Что именно является "открытым универсальным типом"в .NET?

Обобщения - Открытые и закрытые построенные типы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...