2010-07-13 63 views
1

我有一個通用類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#: Generic types that have a constructor?;
  2. An Introduction to C# Generics;
  3. new Constraint (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.我在這裏錯過了一些明顯的東西嗎? =)

在此先感謝!

+1

你到底在問什麼? – SLaks 2010-07-13 20:22:12

+0

@SLaks:用我的**編輯#1 **清楚嗎?否則,我會努力做到這一點。 – 2010-07-13 20:38:30

回答

3

我想拿出很給力,當我的泛型類型DirectorySource是 DirectorySource<Group>類型的,我的搜索是一個GroupSearcher。

爲什麼?這與將搜索器功能封裝到接口中相反,肯定是?你不應該關心實現是什麼,只要它可以搜索正確的條目。

我不認爲構造約束是真的與此有關 - 這將只允許您創建的T不帶參數的新實例...

編輯:我看不到你提出的問題是如何其實有問題。讓我們來看看代碼:

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

所以這裏的TDirectorySource<T>Group。現在構造函數會要求你傳入一個IDirectorySearcher<Group> - 這個userSearcher不是,據我所知。所以這段代碼不會編譯,這就是你想要的。問題在哪裏?

+0

感謝您的回答。爲什麼我想這樣做是因爲,到目前爲止,我們可以做到以下幾點:(請參閱我的編輯#1)。 – 2010-07-13 20:25:38

+0

如果你看到我的**編輯#1 **,你現在可以更好地理解爲什麼我想強制它或約束或任何一個'GroupSearcher',繼續我的例子。 – 2010-07-13 20:31:44

+0

你認爲我應該怎麼做?我的設計不好嗎? = S – 2010-07-13 20:37:36

2

你有沒有考慮:

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); 
+0

+1沒有,我還沒有這一點。 – 2010-07-13 20:30:05

+0

我不認爲這是必要的......我不明白爲什麼會這樣。看我的編輯。 – 2010-07-13 20:39:58

+0

我在一些我認爲有意義的情況下也做了這個。我對這種方法進行編譯的印象是,對TSearcher實例的方法的任何調用都是直接調用實際類型的方法,而不是通過接口進行虛擬調用。我試了一下,發現我的理解實際上並非如此(根據ILDASM)。不是說性能對我來說通常是如此重要,以至於我關心呼叫是否是虛擬的,但至少這是我可以想到的這種方法的一個好處。我錯過了什麼嗎? – 2010-07-13 21:16:02

1

我認爲唯一的方式,你會得到你想要的東西(據我所知)是,如果你添加一個GetSource方法IDirectorySearcher返回的IDirectorySource<T>實現。

+0

+1不是一個壞主意。然而,當我想申請這些未決的變化時,這是我的來源的責任,而不是搜索者。換句話說,我想使我的'DirectorySource'中的GroupSearcher部分成爲我的'GroupSearcher'部分,但是當我想將這兩部分合並在一起時,這樣做的設計很糟糕。 – 2010-07-13 20:36:07