2

Reading the Castle.Core documentation, in this link, they recommend that always overriding the Equals and GetHashCode methods of the classes that implement IProxyGenerationHook.

I have a class called MiHook that implements such interface, but this class doesn't have state. So, my question is, how should I override those two methods if I have a stateless class?

public class MiHook : IProxyGenerationHook {
    public void MethodsInspected() { }

    public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo) { }

    public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo) {
        return methodInfo.Name == nameof(IFoo.Bar);
    }

    // Should I implement both methods like this?
    public override bool Equals(object? obj) => base.Equals(obj);
    public override int GetHashCode() => base.GetHashCode();
}
Marlonchosky
  • 494
  • 5
  • 16
  • 3
    That class has no fields, and thus no state, you can't meaningfully override GetHashCode(). Nothing wrong with Object.GetHashCode(), the hash it generates is very good. Doubtful that the quoted advice is sensible, I don't know the library but I can't imagine you create more than one instance of that class. – Hans Passant Jan 16 '21 at 04:02
  • @HansPassant Yes, it is rare to create more than one instance of the object, but it is good to take into account the clarification since the documentation does not specify how the 2 methods should be implemented. – Marlonchosky Jan 16 '21 at 16:10

2 Answers2

2

I'm not sure what do you mean by stateless class - do you mean that it doesn't have any fields? what is a stateless class?

Base implementation in your example is as good as not overriding at all. You need to ask yourself a question:

What makes two objects of type MiHook equal?

Judging by your implementation of ShouldInterceptMethod it is the Type(IFoo.Bar). If that's the case, I would go for a IFoo.Bar - "dependent" override:

   public class MiHook : IProxyGenerationHook
    {
        public void MethodsInspected() { }
        public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo) { }
        public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
        {
            return methodInfo.Name == nameof(IFoo.Bar);
        }
        public override bool Equals(object obj)
        {
            if (obj == null || obj.GetType() != this.GetType()) return false;
            return obj.GetHashCode() == this.GetHashCode();
        }
        public override int GetHashCode() => typeof(IFoo.Bar).GetHashCode();
    }

To test it:

var mh1 = new MiHook<Foo.Bar>();
var mh2 = new MiHook<Foo.Bar>();
Console.WriteLine(mh1.Equals(mh2)); //True
//your implementation returns False
Ziarek
  • 679
  • 6
  • 14
  • `I'm not sure what do you mean by stateless class - do you mean that it doesn't have any fields?` That's right, a class without fields to store the state of an object, but not necessarily immutable. The code of the GetHashCode method is interesting, I would only change it a bit since as you put it, it is not valid. Something like update # 1 I'll wait a bit to see if there is another answer closer to using the library. Even so thanks! – Marlonchosky Jan 16 '21 at 13:12
0

In the Glimpse project the IProxyGenerationHook is also overridden. Although they still have a private field that is used to override GetHashCode and Equals:

private IEnumerable<IAlternateMethod> methodImplementations;

Here is the link to the source file that contains the methods GetHashCode and Equals.

Maybe it is useful as source of inspiration.

alex-dl
  • 802
  • 1
  • 5
  • 12