2

Is there a way to modify the behavior of a static method at runtime?

for example:

Say I have this class

public class Utility {

    public static void DoSomething(string data){
        //...
    }
}

Is there a way to do something like this:

typeof(Utility).SetMethod("DoSomething", (data) => { /*Do something else...*/ });

Such that if you call Utility.DoSomething it executes the new code?

tt9
  • 5,784
  • 6
  • 42
  • 65

4 Answers4

10

What you want to do is pass the behavior you want as another parameter into the function.

public static void DoSomething(string data, Action<string> operation)
{
    operation(data);
}

This is an oversimplified example, of course. What you actually wind up doing in your own code is going to depend on what operation actually does.


If you're trying to modify the behavior of an existing, compiled, in-production method, and cannot overload or override the method in the usual ways, the only way I know of to do that is CIL Rewriting, possibly using an Aspect Weaver.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • But, if this is the solution, why not just call `operation` directly? – svidgen Feb 24 '16 at 18:00
  • It's a contrived example. For this particular scenario, that's exactly what I would do. But the OP said he wanted to change out the behavior of the method. – Robert Harvey Feb 24 '16 at 18:01
  • @RobertHarvey - I kinda made the assumption that he couldn't change the DoSomething method. Otherwise, he wouldn't be asking the question. – Christine Feb 24 '16 at 18:39
  • I would just create a new class that inherits from Utility. I don't like the idea of injecting code into a static method. – Christine Feb 24 '16 at 19:48
1

Sure.

public class Utility {

    public static Action<String> _DoSomething;

    public static void DoSomething(string data){
        if (_DoSomething != null) {
            _DoSomething();
            return;
        }

        // default behavior here.
    }
}

And to mask the default behavior:

Utility._DoSomething = (data) => { /* do something else */ };
svidgen
  • 13,744
  • 4
  • 33
  • 58
  • For what it's worth, you don't need a member variable to make this work, unless you're setting up some sort of "subscriber" scenario. – Robert Harvey Feb 24 '16 at 18:03
  • @RobertHarvey Not 100% sure what you mean. But, the member variable + method combination is there to avoid breakages when `_DoSomething = null` is called. ... Well ... unless it's *supposed* to break in that case! – svidgen Feb 24 '16 at 18:05
-1

I don't see why you wouldn't just create a new class that inherits from Utility and define a new function that does what you want.

public class Program
{
    static void Main(string[] args)
    {
        if (true)
        {
            Utility.DoSomething("TEST");
        } else
        {
            Util1.DoSomething("TEST");
        }
    }
}

public class Utility
{
    public static void DoSomething(string data)
    {
        //Perform some action
    }
}

abstract class Util1 : Utility
{
    public static new void DoSomething(string data)
    {
        //Perform a different action
    }
}
Christine
  • 621
  • 7
  • 21
  • Also, isn't this question off-topic since the OP is asking us to debug code? Shouldn't this belong on SO? – Christine Feb 24 '16 at 18:13
-1

I think although it is possible to do this you should ask yourself: "Why do I need this functionality"? Usually a method stays as is, and does what it is supposed to do according to its interface which is given by its name and signature. So while you can add additional logic by adding an Action<T>-parameter to your signature you should ask yourself if this won´t break the contract of the interface and therefor what the method was designed for.

Having said this you should consider either overwrite your method if the functionality you need is some kind of "making the same things differently then the parent-class" or extend it by adding a dependency into your consuming class and add some methods to that class that extent the functionality provided by the contained class (see also favour composition over inheritance)

class MyClass {
    Utility MyUtility;

    void ExtraMethod() { /* ... */ }
}

EDIT: As you´re using a static method the opportunity on overwriting is obsolete. However IMO that sounds like a great design-flaw.

Community
  • 1
  • 1
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111