10

後で呼び出すために関数呼び出しを保存する方法は 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 クラスを作成したいと考えています。これは、関数を呼び出す前に待機する時間とともに、すべてのオブジェクトが完全な関数呼び出しを参照できるクラスです。私はすべての時間待機とトリガーを自分で処理するので、それは私が迷子になっている場所ではありません.DelayedFunctionCallerに渡される関数をパッケージ化する方法または正しい方法がわかりません.

キッカーは次のとおりです。DelayedFunctionCaller は、どのオブジェクトが関数を送信しているか、関数が返すもの、または受け取るパラメーターに関係なく、任意の関数を実行できる必要があります**。私のゲームには既に 100 を超えるクラスがあり、目標は、後で呼び出すためにそれらのいずれかからの関数呼び出しを保存できるオブジェクトを作成することです。

したがって、私自身の調査から、Typeクラスを見つけました。呼び出しているオブジェクトのタイプ、関数名を文字列として保存できることを知っています(これは許容できる犠牲ですGetMethod()) MemberInfo。次に、 を使用して、保存されたオブジェクトでも関数を呼び出し、パラメーターを ( の配列としてMemberInfo)Invoke()Objects使用します。

しかし、これはすべて非常に... ハックっぽいです。一度これを調べてみて、Generic Delegatesが自分の行きたい道だと思ったのですが、そこで迷って諦めました。私は正しい軌道に乗っていますか?これがこれを行う唯一の方法ですか?Generic Delegates についてはどうでしょうか、それとも私の問題を解決してくれると思っていたのに気が狂ってしまったのでしょうか?

ありとあらゆる助けをいただければ幸いです。ありがとうございました!

4

2 に答える 2

22

ラムダ式を使用して、アクションとして保存できます。

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

ラムダ内で使用する変数は、その値ではなく、それ自体がキャプチャされることに注意してください。その値が変更された場合、それは関数が呼び出されたときに使用される値になります。詳しい説明については、 Eric Lippertのブログを参照してください。

于 2012-06-03T03:13:56.363 に答える
0

IEnumerableラムダ式に加えて、 orIEnumerable<T>メソッドも使用できます。その後、メソッドを呼び出すには foreach 命令を使用します。たとえば、次の 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();

    }
}
于 2014-10-28T08:56:45.790 に答える