如何在运行时更改静态方法的行为?

时间:2016-02-24 17:18:05

标签: c# reflection

有没有办法在运行时修改静态方法的行为?

例如:

说我有这个班级

public class Utility {

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

有没有办法做这样的事情:

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

这样,如果你致电Utility.DoSomething,它会执行新代码吗?

4 个答案:

答案 0 :(得分:10)

您要做的是将您想要的行为作为另一个参数传递给函数。

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

当然,这是一个过于简单的例子。你在自己的代码中实际做的事情将取决于operation实际做了什么。

如果你试图修改现有的,已编译的in-production方法的行为,并且不能以通常的方式重载或覆盖该方法,我知道这样做的唯一方法是CIL重写,可能使用Aspect Weaver

答案 1 :(得分:1)

不确定

public class Utility {

    public static Action<String> _DoSomething;

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

        // default behavior here.
    }
}

并掩盖默认行为:

Utility._DoSomething = (data) => { /* do something else */ };

答案 2 :(得分:-1)

我不明白为什么你不会只创建一个继承自Utility的新类,并定义一个能够做你想要的新函数。

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
    }
}

答案 3 :(得分:-1)

我认为虽然 可能会这样做,但你应该问自己:“为什么我需要这个功能”?通常一个方法保持原样,并根据其名称和签名给出的接口执行它应该做的事情。因此,当您可以通过在您的签名中添加Action<T> - 参数来添加其他逻辑时,您应该问自己这是否会破坏接口的合同,因此方法是什么是为而设计的。

说完这个之后,你应该考虑覆盖你的方法,如果你需要的功能是某种“以与父类不同的方式制作相同的东西”或扩展它通过在您的消费类中添加一个依赖项并向该类添加一些方法来扩展所包含的类提供的功能(另请参阅favour composition over inheritance

class MyClass {
    Utility MyUtility;

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

编辑:当你使用静态方法时,覆盖的机会已经过时了。然而,IMO听起来像是一个伟大的设计缺陷。