Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hash a delegate function in C#

Tags:

c#

hash

delegates

How can I get a hash of a delegate function in C#. I want to be able to tell if different delegates are being sent into my function. My code looks something like this:

public string GetContent(Func<string, bool> isValid)
{
// Do some work
SomeFunctionToHashAFunction(isValid)
}

I would use .GetHashCode() but the .NET framework doesn't guarantee that these will be unique.

EDIT I have some cached content that I'm validating, but I only want to validate it once. However, if the validation function changes, then I'll need to re-validate the cached content. I'm not sure if the ObjectIdGenerator will work in this instance since I need to identify if two anonymous functions have the same implementation.

like image 725
Noah Avatar asked Jan 20 '23 05:01

Noah


1 Answers

By definition, a hash is not guaranteed to be unique, so hashing is not what you want.

Instead, you want to determine whether the instance of the delegate has been "seen" before. To do this, you could use ObjectIdGenerator:

private static readonly ObjectIdGenerator oidg = new ObjectIdGenerator();

public string GetContent(Func<string, bool> isValid)
{
    bool firstTime;

    oidg.GetId(isValid, out firstTime);

    if (!firstTime)
    {
        ...
    }
}

However, even with this technique there are some pitfalls to be aware of:

  • ObjectIdGenerator stores a reference to each object you pass to it
  • Delegates to the same function are distinct objects, and would therefore return different IDs

Perhaps if you explain what it is you're trying to achieve, there may be a much better way to go about it.

EDIT: Given your updated requirements, I would just define the validation delegate as a property. If the property changes, you know you need to re-validate. GetContent() would therefore not need any parameters:

public Func<string, bool> IsValidHandler
{
    get { return this.isValidHandler; }
    set 
    {
        this.isValidHandler = value;
        this.requiresValidation = true;
    }
}

public string GetContent()
{
    if (this.requiresValidation && this.isValidHandler != null)
    {
        // do validation

        this.requiresValidation = false;
    }

    // return content
}

You might even simplify further and do the validation when the IsValidHandler property is set (not in the GetContent method).

like image 151
Kent Boogaart Avatar answered Jan 28 '23 03:01

Kent Boogaart