C# 如何将函数调用保存在内存中以供以后调用

本文关键字:调用 内存 存在 函数调用 保存 | 更新日期: 2023-09-27 18:36:04

C#中有什么方法可以保存函数调用以供以后调用吗?例如,我希望能够说:

public class MyFunctionCaller
{
    public static void SaveFunctionCallForLater(/* Some parameters*/)
    {
    // Save the Function Call in a variable or a list to be invoked after a set amount of time
   }
}
public class MyProgram
{
    public static void Main()
    {
        // Save a call to 'SpecialFunction' along with its parameters,
        // and maybe the object that's calling it (not applicable in
       // this example context, but important to my question)
        MyFunctionCaller.SaveFunctionCallForLater(/* Stuff */);
    }
    public void SpecialFunction(/* Stuff */)
    {
        // Does some cool stuff
    }
}

让我给你一些上下文:我正在XNA中创建一个游戏,我想创建一个DelayedFunctionCaller类,任何对象都可以引用它来手动完成函数调用,以及在调用函数之前等待的时间。我处理所有的时间等待和触发自己,所以这不是我迷路的地方,我只是不确定如何或正确打包要传递给 DelayedFunctionCall ler 的函数。

这是踢

球者:DelayedFunctionCaller 必须能够运行任何函数,无论哪个对象向它发送函数、函数返回什么或它采用什么参数**。我的游戏中已经有 100 多个类,目标是创建一个对象,该对象可以保存其中任何一个类中的任何函数调用以供以后调用。

所以从我自己的研究中,我找到了Type类,我知道我可以保存对象调用的类型,函数名作为字符串(这是一个可以接受的牺牲),然后用GetMethod()将方法保存在MemberInfo中,然后使用MemberInfoInvoke()来调用函数, 即使在保存的对象上,并使用参数(作为Objects数组)。

但这一切似乎都非常...黑客式的。我曾经尝试过查找这个,并认为通用代表是我想走的路,但我迷失在那里,所以我放弃了。我走在正确的轨道上吗?这是唯一的方法吗?通用代表呢,或者当我认为它可以解决我的问题时,我只是疯了?

感谢任何和所有的帮助。谢谢!

C# 如何将函数调用保存在内存中以供以后调用

您可以使用 lambda 表达式将其另存为操作:

Action functionToCallLater = () => SpecialFunction(/* params */);
// later
functionToCallLater(); // calls SpecialFunction with its parameters

如果函数返回某些内容并且您需要其值,只需改用 Func<T> 类型即可。

int MyMethod(int param) { return param + 1; }
(...)
Func<int> functionToCallLater = () => MyMethod(3);
(...)
int result = functionToCallLater(); // result == 4

请记住,您在 lambda 中使用的任何变量都会被捕获,而不是其值;如果其值发生变化,这将是调用函数时使用的值。请参阅Eric Lippert的博客以获取更深入的解释。

除了 lambda 表达式之外,您还可以使用 IEnumerableIEnumerable<T> 方法。之后,调用方法使用 for each 指令。例如,以下 Unity 引擎代码:

using UnityEngine;
using System.Collections;
public class temp : MonoBehaviour {
    public IEnumerable myMethod1(string str){
        Debug.Log(str);
        yield return null;
    }
    public IEnumerable myMethod2(int number, string str){
        Debug.Log(number+str);
        yield return null;
    }
    System.Action CreateAction(params IEnumerable[] methodsArray){
        return () =>{
            IEnumerable[] methods = methodsArray;
            foreach(IEnumerable method in methods){ foreach(IEnumerable run in method); };
        };
    }

    void Start(){
        System.Action methodGroup = CreateAction(myMethod1("one"),myMethod2(1234,"two"));
        methodGroup();
    }
}