2

I have an interface like:

interface IFoo<in T> {
   ...
}

And I want to have a collection of those classes WITHOUT forcing a specific generic parameter for all collection elements, like:

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

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

   ...
}
fj123x
  • 6,904
  • 12
  • 46
  • 58

2 Answers2

3

Since you don't want to force a specific type, make an abstract class or an interface this way:

interface IFoo { }

And inherit it in your type-specific Foo (with generic parameters), like:

interface IFoo<T> : IFoo {}

This way you can just have a List<IFoo> and add IFoo<T> instead.

More examples:

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);
    }
}
misticos
  • 718
  • 5
  • 22
  • I want to keep the T dynamic – fj123x Oct 05 '19 at 10:57
  • So you want a list of different types? Like IFoo and IFoo in one list? – misticos Oct 05 '19 at 10:58
  • correct, are not scalars, but are different object classes. I would iterate the list and get the type to the object and decide what to do with it – fj123x Oct 05 '19 at 11:01
  • thanks for the response, I was thinking about something like that, then we don't have anything like > , <>, , whatever that I can use? Is this the only way? – fj123x Oct 05 '19 at 11:03
  • @fj123x `we don't have anything like >` Yes we do; the type is called `object`. – Matthew Watson Oct 05 '19 at 11:05
  • This is the only way from what I know. You, probably, could use dynamics but that would be quite weird and just unreadable I guess, not understandable and you won't be able to force inheritance from IFoo. – misticos Oct 05 '19 at 11:05
  • ok, I would wait some minutes to check if there are any other solutions, if not, I will approve the answer. Thanks! – fj123x Oct 05 '19 at 11:07
  • 1
    There is no other solution in C# and in .NET yet, as I know. The CLR does not supporty generic polymorphism on open types. –  Oct 05 '19 at 11:22
1

As indicated by @IvMisticos, to be able to do pseudo generic polymorphism on open type, you can write:

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);

Since there is no diamond operator <> to allow true generic polymorphism on open types in C#, it is the only thing you can do, as I know.

I really dislike this hack that smells bad.

What exactly is an "open generic type" in .NET?

Generics -Open and closed constructed Types

  • Question author doesn't want to force a type for a collection, you misunderstood the question and I did, but I gave a correct answer. You may mark it as useful and delete your own if you want. – misticos Oct 05 '19 at 11:03
  • I perhaps understand what the OP ask for. Answer updated. –  Oct 05 '19 at 11:14
  • okay, so basically you just extended my answer :( dont try to take over what i did – misticos Oct 05 '19 at 11:14