2

I have an two interfaces defined as follows:

public interface IFoo
{
...
}

Public interface IFooWrapper<T> where T : IFoo
{
  T Foo {get;}
}

I want to be able to declare a collection of IFooWrappers but I don't want to specify the implementation of IFoo.

Ideally I want to do something like the:

IList<IFooWrapper<*>> myList;

I can't figure out a way around this.

Matt S
  • 126
  • 6

4 Answers4

2
public interface IFoo
{
...
}

public interface IFooWrapper : IFoo
{
...
}
public interface IFooWrapper<T> : IFooWrapper
 where T : IFoo
{
...
}
IList<IFooWrapper> myList;

this is a way to do what you want

Arsen Mkrtchyan
  • 49,896
  • 32
  • 148
  • 184
2

What's wrong with

IList<IFooWrapper<IFoo>> myList?
Preet Sangha
  • 64,563
  • 18
  • 145
  • 216
0
public class FooWrapper : IFooWrapper<IFoo>
DanDan
  • 10,462
  • 8
  • 53
  • 69
0

What I'm about to suggest is overkill for most situations, since usually you can create an interface higher up in the hierarchy that you can use. However, I think this is the most flexible solution in some ways, and the most faithful representation of what you want:

public interface IFooWrapperUser<U> {
    U Use<T>(IFooWrapper<T> wrapper);
}

public interface IFooWrapperUser {
    void Use<T>(IFooWrapper<T> wrapper);
}

public interface IExistsFooWrapper {
    U Apply<U>(IFooWrapperUser<U> user);
    void Apply(IFooWrapperUser user);
}

public class IExistsFooWrapper<T> : IExistsFooWrapper {
    private IFooWrapper<T> wrapper;
    public IExistsFoo(IFooWrapper<T> wrapper) {
        this.wrapper = wrapper;
    }

    public U Apply<U>(IFooWrapperUser<U> user) {
        return user.Use(foo);
    }

    public void Apply(IFooWrapperUser user) {
        user.Use(foo)
    }
}

Now you can create an instance of an IList<IExistsFooWrapper> which can be used as if it's an IList<IFooWrapper<*>>. The downside is you'll need to create a class to encapsulate the logic you want to run on each element:

private class FooPrinter : IFooWrapperUser<string> {
    public string Apply<T>(IFooWrapper<T> wrapper) {
        return wrapper.Foo.ToString();
    }
}

...
    IFooWrapperUser<string> user = new FooPrinter();
    foreach (IExistFooWrapper wrapper in list) {
        System.Console.WriteLine(wrapper.Apply(user));
    }

...
kvb
  • 54,864
  • 2
  • 91
  • 133