3

I'm having a problem writing a generic method to retrieve AD Groups or Users with a parameter that can be one of two types - either System.DirectoryServices.AccountManagement GroupPrincipal or UserPrincipal

The method is as follows:-

private static IEnumerable<string> GetGroupsOrUsers<T>(T GroupOrUserPrincipal)
{
   PrincipalSearcher ps = new PrincipalSearcher();
   ps.QueryFilter = GroupOrUserPrincipal;

   etc.........
}

The problem is the GroupOrUserPrincipal is showing the following error:-

Cannot implicitly convert type 'T' to System.DirectoryServices.AccountManagement.Principal

Am I able to do this or am I missing something ?

6
  • 3
    Quick question. Why don't you write one method for groups and another one for users? Commented Nov 9, 2011 at 9:26
  • That's what I had done but just wanted to streamline it a bit using just one method - there is more code in this method so really it was to avoid duplication. Commented Nov 9, 2011 at 9:29
  • GroupPrincipal and UserPrincipal are derived from Principal? Commented Nov 9, 2011 at 9:31
  • Couple of good answers pointing to a type constraint - but those will fail if you don't want your code to work for any other principal types, e.g. a ComputerPrincipal (i.e. did you mean that you want it to work for the two types you've listed, and no others?) Commented Nov 9, 2011 at 9:34
  • @J. Kommer - my point was, the OP requested something that would work for GroupPrincipal and UserPrincipal - I was trying to ask whether that was an exclusive list of types that this method should work for... Commented Nov 9, 2011 at 9:41

4 Answers 4

6

You should restrict T to types that your method makes sense for:

private static IENumerable<string> GetGroupsOrUsers<T>(T GroupOrUserPrincipal)
        where T : Principal
{
      // .....

That prevents calls of GetGroupsOrUsers<int>, and lets T be implicitly converted to Principal, fixing your error (or so I hope).

Sign up to request clarification or add additional context in comments.

3 Comments

Very cool. Never thought about doing this. Do you know the Pro's and Con's of using this?
@thats_how_i_feel: You can read more about this at msdn.microsoft.com/en-us/library/…. I don't know any cons, pros are mostly type safety and re-usability.
Well I like it. I feel like it encourages better object oriented programming. If you have three classes that all have a method that does essentially the same thing and you want to make another method in another class that utilizes their similar methods, you shouldn't have to make three new methods, right? Anyways, this section of Wikipedia's C# page helped me understand type parameters better.
3

Possibly you want to look at Generic Contraints in particular a derivation contraint where your various T objects all impliment a given interterface. Eg

where T : Principle

Comments

3

You need to specify a type parameter constraint; for example:

private static IEnumerable<string> GetGroupsOrUsers<T>(T GroupOrUserPrincipal) where T: Principal

This limits the classes that can be used as T to only classes of type Principal or a subclass of Principal. The C# compiler then knows that everything passed to GetGroupsOrUsers(...) will be of a type compatible with Principal and will no longer error.

Comments

0

You have to write a cast in this line:

ps.QueryFilter = (Principal) GroupOrUserPrincipal; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.