Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a C# method "implement" a delegate

Does anyone know of a way in C# to force a method to "implement" a delegate?

Consider this greatly simplified example: (loosely based on a real world scenario I've encountered)

    private delegate int ComputationMethod(int termA, int termB, int termC, int termD);

    private int computationHelper(int termA, int termB, int termC, int termD, ComputationMethod computationMethod)
    {
        //Some common logic^
        int answer = computationMethod(termA, termB, termC, termD);
        //Some more common logic^
        return answer;
    }

    public int ComputeAverage(int termA, int termB, int termC, int termD)
    {
        //^^
        return computationHelper(termA, termB, termC, termD, computeAverage);
    }

    public int ComputeStandardDeviation(int termA, int termB, int termC, int termD)
    {
        //^^
        return computationHelper(termA, termB, termC, termD, computeStandardDeviation);
    }        

    //Is there some way to force this method's signature to match ComputationMethod?
    private static int computeAverage(int termA, int termB, int termC, int termD) 
    {
        //Implementation omitted
    }

    //Is there some way to force this method's signature to match ComputationMethod?
    private static int computeStandardDeviation(int termA, int termB, int termC, int termD)
    {
        //Implementation omitted
    }

^ - Assume this logic cannot be called from ^^.

In this example, I'd essentially like to "force" methods to conform to the ComputationMethod signature in the same way an interface forces a class to implement certain methods. Something equivalent to:

private static int computeAverage(int termA, int termB, int termC, int termD) : ComputationMethod
    {
        //Implementation omitted
    }

Yes, obviously I can just copy and paste the method signature, but conceptually these implementations of ComputationMethod could be in an entirely different class without access to the source. Also, if someone then comes along and changes a method signature that is supposed to conform to a certain delegate, the source code will break, but it may break silently in an entirely different module.

Thanks for any help.

like image 647
MgSam Avatar asked Feb 21 '23 03:02

MgSam


2 Answers

C# does not support this.

However, you can simulate it by simply putting the method into a delegate:

static readonly ComputationMethod _ForceCompliance = ComputeAverage;
private static int ComputeAverage(int termA, int termB, int termC, int termD) { ... }

Changing the method or delegate signature would result in a compiler error one line above the method.

(doing this with instance methods would require a constructor call)

For added efficiency, you could do this in an unused nested class and/or in #if DEBUG.

Either way, make sure to leave an explanatory comment.

like image 112
SLaks Avatar answered Feb 23 '23 17:02

SLaks


A delegate has a signature composed of the return type and the parameters (types and order) - if you have a method that matches that signature, it will match the delegate.

That the methods you are asking about are static makes no difference.

There is no direct way to ensure that any specific method will conform to a delegate signature - you could create interface with methods that conform to the signature and ensure it is used and implemented.

like image 31
Oded Avatar answered Feb 23 '23 16:02

Oded