2016-02-24 81 views
1

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

例如:

说我有这个类

public class Utility { 

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

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

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

这样的,如果你调用Utility.DoSomething它执行新码?

+0

你可以将lambda存储在一个变量中并让'DoSomething'调用变量?然后,只要您想存储新的lambda,就可以更改该变量。但我不是C#开发者... –

+1

我提供了一个答案,因为它非常简单。但是,我相信这个问题属于SO。 – svidgen

+1

也使用非静态方法可能是一个更好的主意。 –

回答

10

你想要做的是通过你想要的另一个参数到函数的行为。

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

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


如果你想修改现有的,编制而成的,制作方法的行为,并不能超载或一般的方式覆盖的方法,我知道这样做的唯一途径是CIL重写,可能使用Aspect Weaver

+0

但是,如果这是解决方案,为什么不直接调用'operation'呢? – svidgen

+0

这是一个人为的例子。对于这个特定的场景,这正是我要做的。但是OP表示他想改变方法的行为。 –

+0

@RobertHarvey - 我有点假设他无法改变DoSomething方法。否则,他不会问这个问题。 – Hill

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 */ }; 
+0

对于它的价值,你不需要一个成员变量来完成这项工作,除非你设置某种“订户”方案。 –

+0

@RobertHarvey不是100%确定你的意思。但是,当调用_DoSomething = null时,成员变量+方法组合可以避免破坏。 ......呃......除非在这种情况下它被认为会被打破! – svidgen

0

我不明白为什么你不会创建一个继承自实用工具的新类,并定义一个新的函数来实现你想要的功能。

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

另外,自从OP要求我们调试代码以来,这个问题不是问题吗?这不应该属于SO吗? – Hill

0

我觉得虽然可能做到这一点你应该问自己:“为什么我需要这个功能”?通常情况下,一种方法保持不变,并根据其名称和签名给出的接口做它应该做的事情。所以虽然你可以通过添加Action<T>参数添加额外的逻辑你的签名,你应该问自己,这是否不会打破接口的合同,因此什么方法是为设计的。

话虽如此,你应该考虑要么覆盖你的方法,如果你需要的功能是某种“做不同的同样的事情,然后父级”或它通过添加依赖到你的消费类扩展和一些方法添加到类程度由所包含的类提供的功能(也见favour composition over inheritance

class MyClass { 
    Utility MyUtility; 

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

编辑:由于you're使用静态方法上重写的机会是过时的。然而,IMO听起来像是一个伟大的设计缺陷。