(パラメーター付きの)関数をパラメーターとして渡しますか?

StackOverflow https://stackoverflow.com/questions/604048

  •  03-07-2019
  •  | 
  •  

質問

関数をパラメーターとして渡すことができるジェネリックを作成したいのですが、この関数にはパラメーター自体が含まれている可能性があります...

int foo = GetCachedValue("LastFoo", methodToGetFoo)

そのような:

protected int methodToGetFoo(DateTime today)
{ return 2; // example only }

本質的に、キャッシュの値をチェックするメソッドが必要です。そうでない場合は、渡されたメソッドに基づいて値を生成します。

思考?

役に立ちましたか?

解決

Func<T>

が必要なようです
T GetCachedValue<T>(string key, Func<T> method) {
     T value;
     if(!cache.TryGetValue(key, out value)) {
         value = method();
         cache[key] = value;
     }
     return value;
}

呼び出し側はこれをさまざまな方法でラップできます。単純な関数の場合:

int i = GetCachedValue("Foo", GetNextValue);
...
int GetNextValue() {...}

または引数が関係する場合、クロージャ:

var bar = ...
int i = GetCachedValue("Foo", () => GetNextValue(bar));

他のヒント

System.Actionとラムダ式を使用する(無名メソッド)。例

    public void myMethod(int integer){

    //Do something

}

public void passFunction(System.Action methodWithParameters){

    //Invoke
    methodWithParameters();

}

//...

//Pass anonimous method using lambda expression
passFunction(() => myMethod(1234));

独自のデリゲートを作成できますが、C#3.0では、組み込みのFunc<T>デリゲートファミリを使用してこの問題を解決する方が便利な場合があります。例:

public int GetCachedValue(string p1, int p2,
                          Func<DateTime, int> getCachedValue)
{
    // do some stuff in here
    // you can call getCachedValue like any normal function from within here
}

このメソッドは、文字列、int、およびDateTimeを取得してintを返す関数の3つの引数を取ります。例:

int foo = GetCachedValue("blah", 5, methodToGetFoo);   // using your method
int bar = GetCachedValue("fuzz", 1, d => d.TotalDays); // using a lambda

異なるFunc<T, U, V...>などのタイプがフレームワークに存在して、異なる量の引数を持つメソッドに対応します。

メソッドのデリゲートを作成methodToGetFoo

public delegate object GenerateValue(params p);
public event GenerateValue OnGenerateValue;

デリゲートを使用するようにGetCachedValueを定義します

int GetCachedValue(string key, GenerateValue functionToCall);

OnGenerateValueの実装では、パラメーターを確認できます。

ここは私が始めた簡単なものですそれをもう少し進めることができます(私が商業プロジェクトでやったように)。

私の場合、これはWebサービス呼び出しをキャッシュするためのもので、次のようなものが使用されました。

WebService ws = new WebService();
var result = ws.Call( x => x.Foo("bar", 1));  // x is the ws instance
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top