none
Equal but not same HashCode in System.DirectoryServices.AccountManagement.Principial RRS feed

  • Question

  • Hi,

    I tried to determine if a user is a member of a ActiveDirectory Group via System.DirectoryServices.AccountManagement. This group.Member.Contains(user) was always false but the user was a member of the group. Look at following sourecode:

            private void testMe(UserPrincipal user, string groupName)
            {
                using (GroupPrincipal group = this.getGroup(groupName))
                {
                    foreach (Principal p in group.Members)
                    {
                        if (p.Equals(user))
                        {
                            Console.WriteLine("Equal");
                        }
                        else
                        {
                            Console.WriteLine("not Equal");
                        }
    
                        if (p.GetHashCode() == user.GetHashCode())
                        {
                            Console.WriteLine("Hash is Equal");
                        }
                        else
                        {
                            Console.WriteLine("Hash is not Equal");
                        }
                    }
    
                    if (group.Members.Contains(user))
                    {
                        Console.WriteLine("Member of Group");
                    }
                    else
                    {
                        Console.WriteLine("Not Member of Group");
                    }
                }
            }
    

    "group" has 3 members. One of them is "user". The output is:

    not Equal
    Hash is not Equal
    not Equal
    Hash is not Equal
    Equal
    Hash is not Equal
    Not Member of Group

    As you can see, there is one "Equal" but the HashCode of both objects are not equal. Thus Contains() fails to find the user object.

    I am totally confused about this behavior. Can anyone explain? Is this a bug?

    Thanks

    Daniel

    Friday, May 4, 2012 7:08 AM

Answers

All replies

  • It's a bug. The Principal class overrides Equals and GetHashCode but the GetHashCode simply returns base.GetHashCode. That's wrong.

    However I'm not sure that the hash code thing has something to do with Contains. As far as I can tell Contains doesn't make use of it, after all that collection is not a hashtable. What seems to me is that Contains doesn't make use of Equals, it has its own methods of checking for equality.

    Friday, May 4, 2012 3:39 PM
    Moderator
  • Hi,

    as far as I understand Contains() does a "quick search" via GetHashCode(). Then the method compares the found objects (hash functions are having collisisions) by Equals().

    Can someone agree? I am close to file a bug ;)

    regards

    Daniel

    Friday, May 4, 2012 5:16 PM
  • I'm not sure why do you think Contains does such a quick search. Is that documented somewhere? Unless it is a hashtable it shouldn't do that.

    I'd file a Connect bug, I'm not sure about Contains but Principal.GetHashCode is certainly broken.

    Friday, May 4, 2012 5:26 PM
    Moderator
  • I have opend a Connect Bug.

    Thanks for your replies

    Daniel

    Monday, May 7, 2012 1:56 PM