C # Generics и Коллекции - PullRequest
       6

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

2 голосов
/ 04 августа 2009

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

public interface IFoo
{
...
}

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

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

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

IList<IFooWrapper<*>> myList;

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

Ответы [ 4 ]

2 голосов
/ 04 августа 2009

Что не так с

IList<IFooWrapper<IFoo>> myList?
2 голосов
/ 04 августа 2009
public interface IFoo
{
...
}

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

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

0 голосов
/ 04 августа 2009

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

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 голосов
/ 04 августа 2009
public class FooWrapper : IFooWrapper<IFoo>
...