Как я могу использовать пользовательскую реализацию универсального интерфейса с закрытыми типами? - PullRequest
2 голосов
/ 07 ноября 2011

Допустим, я хочу указать, какую реализацию универсального интерфейса использовать в моем классе. Это просто (если немного уродливо), если класс использует его для хранения другого открытого типа:

class Foo<T> where T : IList<Bar>, new()
{
    private T _list = new T();
}
class Bar{}

Затем мы можем создать новый экземпляр foo: new Foo<List<Bar>>()

Но что происходит Bar - это частный класс в Foo:

class Foo<T> where T : IList<Bar>, new()
{
    private T _list = new T();
    class Bar{}
}

Очевидно, что это не удается, потому что Foo не может выставить Bar в ограничениях его типов, и нет способа создать экземпляр new Foo<List<Bar>>()

Я мог бы придерживаться разоблачения object:

class Foo<T> where T : IList<object>, new()
{
    private T _list = new T();
    class Bar{}
}

Но затем я использую object до Bar каждый раз, когда использую интерфейс.

Какой мой лучший вариант здесь?

Ответы [ 3 ]

1 голос
/ 07 ноября 2011

Назначение private - разрешить доступ только по коду из того же класса. Просто то, что вы пытаетесь сделать, не правильно. лучше измените этот приватный на другой модификатор доступа в соответствии с вашими требованиями.

0 голосов
/ 08 ноября 2011

Я бы сказал, что ваш лучший вариант:

class Foo
{
    private List<Bar> _list = List<Bar>();
    class Bar{}
}

Единственная причина, по которой я могу сделать Foo универсальным классом для переноса списка некоторых частных вложенных классов, заключается в том, что у вас есть частная иерархия вложенных классов с наследниками Bar. И, если бы это было так, вы могли бы просто представить какой-то фабричный метод, который принял параметр, необходимый, чтобы сообщить Foo, какие клиенты подкласса хотят. Если вы сохраняете тип списка и список закрытыми, делать общедоступный API класса не имеет смысла, IMO. Вы требуете, чтобы клиенты предоставляли тип, к которому у них нет доступа или контроля.

0 голосов
/ 07 ноября 2011

Как насчет предоставления параметра второго типа в классе Foo, представляющего тип экземпляра коллекции, например:

class Foo<TList, TItem> where TList : IList<TItem>, new()
{
    private IList<TItem> _list = new TList();

    public Foo()
    {
    }


    public void Add(TItem item)
    {
        _list.Add(item);
    }
}

А затем создайте конкретный класс для удержания бара, например

class BarFoo : Foo<List<BarFoo.Bar>, BarFoo.Bar>
{
    class Bar { }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...