Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用另一个方法体替换方法体_C#_Reflection - Fatal编程技术网

C# 用另一个方法体替换方法体

C# 用另一个方法体替换方法体,c#,reflection,C#,Reflection,我想做的是用另一个方法的主体替换一个(静态)方法的主体,同时保留原始方法的主体 让我从一个例子开始: public static class Program { public static void Main(string[] args) { switch (new Random().Next(3)) { case 0: // Change MainFunction's body into a

我想做的是用另一个方法的主体替换一个(静态)方法的主体,同时保留原始方法的主体

让我从一个例子开始:

public static class Program
{
    public static void Main(string[] args)
    {
        switch (new Random().Next(3))
        {
            case 0:
                // Change MainFunction's body into a's body, storing the original body somewhere else
                break;
            case 1:
                // Change MainFunction's body into b's body, storing the original body somewhere else
                break;
            case 2:
                // Change MainFunction's body into c's body, storing the original body somewhere else
                break;
        }
        MainFunction(null);
    }

    public static void MainFunction(object someParameter)
    {
        Console.Write("The method called is: ");
    }

    private static void a(object someParameter)
    {
        // Call the 'base' method
        Console.WriteLine("a");
    }

    private static void b(object someParameter)
    {
        // Call the 'base' method
        Console.WriteLine("c");
    }

    private static void c(object someParameter)
    {
        // Call the 'base' method
        Console.WriteLine("c");
    }
}
预期的输出是:'调用的方法是:'和'a','b'或'c'。 我知道这个例子是完全无用的,这就是为什么它是一个例子,但我只想知道如何实现这一点

有人知道如何做到这一点吗

编辑:
我不是在寻找一名代表,我知道他们非常有用,但正如我所说,这是一个例子,我知道如何实现这一点

我还知道您应该重复使用随机数,以避免重新计算初始数据的开销,并让GC休息一下


这个例子只是为了演示结果,当然这个例子可以通过使用
委托
操作
,或者如果您还想要返回值
Func
,来轻松解决,但我不想寻找那个解法。

听起来您真正想要的是委托。

您可以创建类型为
Action
的委托,并将其分配到代码中,然后根据需要在
main函数
中调用该委托

private Action<object> MainFunction;

private Random rand = new Random();

public static void Main(string[] args)
{
    switch (rand.Next(3))
    {
        case 0: MainFunction = a; break;
        case 1: MainFunction = b; break;
        case 2: MainFunction = c; break;
    }
    MainFunction(null);
}
私人行动主功能;
private Random rand=new Random();
公共静态void Main(字符串[]args)
{
开关(随机下一个(3))
{
案例0:MainFunction=a;中断;
情况1:MainFunction=b;中断;
情况2:MainFunction=c;中断;
}
main函数(空);
}
此外,虽然可能仅用于说明目的,但在代码中使用
new Random()
可能不是您想要的。创建
Random
的新实例将重置随机数序列。除非您只获取这一个随机值,否则您可能希望存储随机数生成器

编辑:我认为您需要更好地解释为什么使用代理的方法不足以解决您的问题。确定您需要的关键要求和完整的相关示例将大大有助于您获得满意的答案。通常,不可能在运行时替换现有类的方法体-这将违反CLR安全模型。您所能做的最好的事情就是在运行时生成一个新类,并发出具有适当签名和主体的方法——但是,我不清楚这与使用委托有什么不同

或者,您也可以使用PostSHARP之类的工具,并使用面向方面的技术在运行时更改MainFunction()的行为。例如,PostSHARP中的MethodBoundaryAspect允许您在方法之前、之后或代替方法运行任意代码。然而,如果不能更好地解释您试图解决的问题,我们只能猜测。。。这不会让你走多远。

你在找什么?(大标题)

publicstaticrandom rand=newrandom();
公共静态void Main(字符串[]args)
{
Action=null;
开关(随机下一个(3))
{
案例0:
行动=a;
打破
案例1:
行动=b;
打破
案例2:
行动=c;
打破
}
动作(空);
}

(对您来说也是固定随机的,应该重复使用实例而不是频繁创建新实例,否则序列不会是随机的)

据我所知,不可能真正交换方法体。但根据您的设置,您可以使用代理来解决此问题。下面是一些伪代码,为您提供指导:

public static Action<object> MethodToCall;
然后调用以下函数,而不是main函数(null):

MethodToCall(null)
C#是一种语言。这意味着编译器读取您的C#代码,并将其转换为汇编语言.exe或.dll文件

据我所知,当编译器从代码生成方法时,方法体完全独立于方法的名称。方法的名称只是与代码块关联的属性

运行时引擎使用自顶向下的逻辑;它从程序的开头(Main方法)开始,每次执行一条语句。例如,当它遇到相当于“callmymethod”的汇编语言时,它只需移动到与“MyMethod”关联的代码块中的第一条语句,并从那里开始执行。“MyMethod”代码块中的所有语句执行完毕后,运行时引擎返回到调用MyMethod之前的位置

因此,方法名称的3个主要用途是

  • 允许您和其他程序员使用您的代码或程序集可以识别该方法并将其与其他方法区分开来
  • 允许编译器知道与源代码中的方法调用关联的程序集级方法
  • 最后,在运行时执行该方法关联的代码块
  • 您试图做的事情绕过了为每个方法拥有唯一签名的所有目的。现在,我知道这只是一个示例程序,所以我不会指出这是什么糟糕的做法。但是,我担心在运行时,如果不使用委托,或者像前面提到的那样,使用委托,将方法名称从其关联的主体中删除是完全不可能的

    回到C#的静态特性,您试图做的是语言的一个更常见的特性,如JavaScript、PHP、Lua等。例如,在JavaScript中,您可以定义一个函数(相当于一个方法的JavaScript),将其分配给一个变量,然后根据需要修改变量的值,并动态调用它。使这一功能成为可能的是代码的执行方式:与C#和其他静态类型语言不同,每个语句都被读取为人类可读的源代码,interpr
    MethodToCall = (someParameter) => {
        MainFunction(someParameter);
        a(someParameter);
    }
    
    MethodToCall(null)