C # Generics и Коллекции

2

У меня есть два интерфейса, определяемые следующим образом:

public interface IFoo
{
...
}

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

Я хочу, чтобы иметь возможность объявлять коллекцию IFooWrappers, но я не хочу указывать реализацию IFoo.

В идеале я хочу сделать что-то вроде:

IList<IFooWrapper<*>> myList;

Я не могу найти способ обойти это.

Теги:
generics
collections

4 ответа

2

Что случилось с

IList<IFooWrapper<IFoo>> myList?
  • 0
    На самом деле! List <IFooWrapper <IFoo >> myList = new List <IFooWrapper <IFoo >> ();
  • 1
    За исключением того, что он не будет работать ... например, IFooWrapper <Foo> не наследует IFooWrapper <IFoo>, даже если Foo реализует IFoo ... (кроме случаев, когда вы используете C # 4, который реализует ковариацию)
Показать ещё 2 комментария
2
public interface IFoo
{
...
}

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

Это способ сделать то, что вы хотите

  • 0
    Первая мысль
0

То, что я собираюсь предложить, является излишним для большинства ситуаций, поскольку обычно вы можете создать интерфейс выше в иерархии, которую вы можете использовать. Однако я считаю, что это наиболее гибкое решение в некотором роде и наиболее точное представление о том, что вы хотите:

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

Теперь вы можете создать экземпляр IList<IExistsFooWrapper>, который можно использовать, как если бы он был IList<IFooWrapper<*>>. Недостатком является создание класса для инкапсуляции логики, которую вы хотите запускать для каждого элемента:

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

...
0
public class FooWrapper : IFooWrapper<IFoo>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню