MemberEqualityComparer.Equals returning true where members aren't equal

Cameron's Avatar

Cameron

05 May, 2010 04:20 PM via web

The latest git version of FluentNHibernate isn't mapping my object model.

I believe it is because of the following code in Member.cs:

public class MemberEqualityComparer : IEqualityComparer<Member>
{
    public bool Equals(Member x, Member y)
    {
        return x.MemberInfo.MetadataToken.Equals(y.MemberInfo.MetadataToken);
    }

    public int GetHashCode(Member obj)
    {
        return obj.MemberInfo.MetadataToken.GetHashCode();
    }
}

I set a breakpoint inside equals, and am getting the following:
x.MemberInfo.MetadataToken = 385875970
y.MemberInfo.MetadataToken = 385875970
x.MemberInfo.Module = {Dms.Core.dll}
y.MemberInfo.Module = {Common.Core.dll}

The MSDN page on MetadataToken indicates that it will only uniquely identify metadata in combination with Module:
http://msdn.microsoft.com/en-us/library/system.reflection.memberinf...

A potential fix, in that case, would be:

public class MemberEqualityComparer : IEqualityComparer<Member>
{
    public bool Equals(Member x, Member y)
    {
        return x.MemberInfo.MetadataToken.Equals(y.MemberInfo.MetadataToken) && x.MemberInfo.Module.Equals(y.MemberInfo.Module);
    }

    public int GetHashCode(Member obj)
    {
        return obj.MemberInfo.MetadataToken.GetHashCode() & obj.MemberInfo.Module.GetHashCode();
    }
}

Right? Seems to work for me.

Thanks!
Cameron

  1. 2 Posted by Cameron on 05 May, 2010 04:31 PM

    Cameron's Avatar

    In the same file, Member.Equals suffers the same problem:

        public bool Equals(Member other)
        {
            return other.MemberInfo.MetadataToken.Equals(MemberInfo.MetadataToken);
        }
    

    I've changed it in my code to

        public bool Equals(Member other)
        {
            return other.MemberInfo.MetadataToken.Equals(MemberInfo.MetadataToken) && other.MemberInfo.Module.Equals(MemberInfo.Module);
        }
    
  2. Support Staff 3 Posted by James Gregory on 05 May, 2010 05:37 PM

    James Gregory's Avatar

    Good catch! I wrote this piece of code while I was offline, and meant to
    look up the implications of using MetadataToken next time I got on. Thanks

  3. 4 Posted by Chris Stavropoulos on 12 May, 2010 05:39 PM

    Chris Stavropoulos's Avatar

    I can confirm this issue. The fix does indeed work.

    From the Microsoft documentation on the MetadataToken, it is only unique within a module.

    http://msdn.microsoft.com/en-us/library/system.reflection.memberinf...

  4. Support Staff 5 Posted by James Gregory on 16 May, 2010 05:02 PM

    James Gregory's Avatar

    I've applied Cameron's changes to the codebase. Thanks!

  5. James Gregory closed this discussion on 16 May, 2010 05:02 PM.

Comments are currently closed for this discussion. You can start a new one.