Ограничение конструктора для универсальных типов или просто проверить наличие ограничений в моем конструкторе универсальных типов? - PullRequest
1 голос
/ 14 июля 2010

У меня есть универсальный класс DirectorySource<T>, который зависит от интерфейса IDirectorySearch<T>.

Оба являются обобщенными и имеют одинаковое ограничение типа:

public class DirectorySource<T> where T : IDirectoryEntry { }

public interface IDirectorySearcher<T> where T : IDirectoryEntry { }

Так, например, когда я хочу, чтобы источник манипулировал группами, я бы пошел следующим образом:

IDirectorySearcher<Group> groupSearcher = new GroupSearcher(ROOT, SCOPE);
IDirectorySource<Group> groups = new DirectorySource(groupSearcher);

То, что я хочу придумать, - это заставить, когда мой универсальный тип DirectorySource<T> относится к типу DirectorySource<Group>, что мой поисковик - GroupSearcher, и я не хочу, чтобы один мог передать его UserSearcher, например.

Я прочитал следующие статьи:

  1. C #: универсальные типы, имеющие конструктор? ;
  2. Введение в C # Generics ;
  3. новое ограничение (C # Reference) .

И я, похоже, не понимаю, как справиться с такого рода ограничениями в моем классе. На данный момент у меня есть следующее:

public class DirectorySource<T> where T : IDirectoryEntry {
    public DirectorySource(IDirectorySearcher<T> searcher) {
        Searcher = searcher;
    }

    public IDirectorySearcher<T> Searcher { get; private set; }
}

А потом у меня тоже следующее:

public class GroupSearcher : IDirectorySearcher<Group> {

    public GroupSearcher(DirectoryEntry root, SearchScope scope) {
        NativeSearcher = new DirectorySearcher();
        NativeSearcher.SearchRoot = root;
        NativeSearcher.SearchScope = scope;
    }

    // Implementing interface...
}

Я не могу просто заменить тип свойства Searcher, так как это приведет к тому, что мой универсальный класс станет неуниверсальным.

Любая идея или что-то, что я не правильно понял об этом ограничении конструктора о том, как я должен идти с тем, чего я хочу достичь?

РЕДАКТИРОВАТЬ # 1

Причина, по которой я хочу это сделать, заключается в том, что можно сделать следующее:

IDirectorySearcher<User> userSearcher = new UserSearcher(ROOT, SCOPE);
IDirectorySource<Group> groups = new DirectorySource<Group>(userSearcher);

Мне кажется, это неправильно ...

1. Я что-то упускаю здесь очевидное? =)

Заранее спасибо!

Ответы [ 3 ]

3 голосов
/ 14 июля 2010

Что я хочу придумать, так это заставить, когда мой универсальный тип DirectorySource имеет тип DirectorySource<Group>, мой поисковик является GroupSearcher.

Почему?Разумеется, это противоречит цели инкапсуляции функциональности поисковика в интерфейс?Вам не нужно заботиться о том, что такое реализация, если она может искать нужные типы записей.

Я не думаю, что ограничения конструктора действительно актуальны здесь - это только позволит вам создать новыйэкземпляр T без аргументов ...

РЕДАКТИРОВАТЬ: Я не вижу, как ваша предложенная проблема на самом деле проблема.Давайте посмотрим на код:

IDirectorySearcher<User> userSearcher = new UserSearcher(ROOT, SCOPE);
IDirectorySource<Group> groups = new DirectorySource<Group>(userSearcher);

Так что здесь T для DirectorySource<T> равно Group.Теперь конструктор потребует, чтобы вы передали IDirectorySearcher<Group> - а userSearcher, насколько я вижу, нет.Так что этот код не будет компилироваться, а это то, что вы хотите.Где проблема?

2 голосов
/ 14 июля 2010

Рассматривали ли вы:

public class DirectorySource<TValue, TSearcher> 
            where TValue : IDirectoryEntry 
            where TSearcher : IDirectorySearcher<T>, new() 
{ 
    public DirectorySource(TSearcher seacher) 
    { 
        Searcher = seacher
    } 

    public TSearcher Searcher { get; private set; } 
} 

IDirectorySearcher<Group> groupSearcher = new GroupSearcher(ROOT, SCOPE);     
var  groups = new DirectorySource<Group, GroupSearcher>(groupSearcher); 
1 голос
/ 14 июля 2010

Я думаю, что единственный способ получить то, что вы хотите (насколько я понимаю), - это добавить GetSource метод к IDirectorySearcher, который возвращает реализацию IDirectorySource<T>.

...