开发者

Constructor constraint on generic types or simply check for constraint within my generic type constructor?

I have a generic class DirectorySource<T> which depends on an interface IDirectorySearch<T>.

Both are generics and have the same type constraint:

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

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

So, for instance, when I want a source to manipulate groups, I would go this way:

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

What I wish to come up with is to force, when my generic type DirectorySource<T> is of DirectorySource<Group> type, that my searcher is a GroupSearcher, and I don't want one to be able to pass in a UserSearcher, for example.

I have read the following articles:

  1. C#: Generic types that have a constructor?;
  2. An Introduction to C# Generics;
  3. new Constraint (C# Reference).

And I don't seem to get how to handle this kind of constraint with my class. As for now, I have the following:

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

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

And then, I have the following too:

public class GroupSearcher : IDirectorySearcher<Group> {

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

    // Implementing interface...
}

I can't just replace the Searcher property type, as this would cause my generic class to become non-generic.

Any idea or something I didn't understand correctly about this constructor constraint on how I should go with what I want to accomplish?

EDIT #1

The reason I want to do so is because one could do the fo开发者_如何学JAVAllowing:

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

This seems incorrect to me...

1. Am I missing something obvious here? =)

Thanks in advance!


What I wish to come up with is to force, when my generic type DirectorySource is of DirectorySource<Group> type, that my searcher is a GroupSearcher.

Why? That's going against the point of encapsulating the searcher functionality into an interface, surely? You shouldn't care what the implementation is, so long as it can search for the right kinds of entry.

I don't think constructor constraints are really relevant here - that would only allow you to create a new instance of T with no arguments...

EDIT: I can't see how your proposed problem is actually a problem. Let's look at the code:

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

So here the T for DirectorySource<T> is Group. Now the constructor will require you to pass in an IDirectorySearcher<Group> - which userSearcher isn't, as far as I can see. So this code wouldn't compile, which is what you want. Where's the problem?


Have you considered:

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


I think the only way you're going to get what you want (as I understand it) is if you add a GetSource method to IDirectorySearcher which returns an implementation of IDirectorySource<T>.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜