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();
}
2
  • 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. Commented Jan 16, 2021 at 4: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. Commented Jan 16, 2021 at 16:10

2 Answers 2

2
+50

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
Sign up to request clarification or add additional context in comments.

1 Comment

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!
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.

1 Comment

Thank you, too bad its class is not stateless

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.