2009-03-02 22 views
20

は私がパラメータとして関数を渡すことができたにジェネリックを作成したい、しかし、この関数はパラメータので、自分自身を...含むことができ関数(パラメータ付き)をパラメータとして渡す?

int foo = GetCachedValue("LastFoo", methodToGetFoo) 

このようなこと:基本的に私はしたい

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

キャッシュの値をチェックするメソッドを持つ。そうでなければ、渡されたメソッドに基づいて値を生成する。

思考?

+0

私はこれを行う方法はわかりませんが、この質問は私が知る限りジェネリックスとは関係がないようです。 – recursive

+0

それはちょっとしています。おそらく "代理人"は "ジェネリックス"を置き換えるべきでしょう。 – mquander

+0

申し訳ありませんが、これを処理する汎用メソッドを作成していたので、関連性があると仮定しました。しかし、合意は本当に代理人に関連しているので、私は更新します。ありがとう – klkitchens

答えて

37

それはあなたが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)); 
+1

私は非常に近いですが、ジェネリックのparmsを取得する方法を理解できませんでした。最後のオプションは、閉鎖とキーでした!魅力のように動作します。 – klkitchens

+2

ここに本当に古いものがありましたが、閉鎖部分は私が探していたものでした –

4

は独自のデリゲートを作成することができますが、C#3.0であなたを内蔵して使用することがより便利かもしれませんFunc<T>この問題を解決する代理人家族。例:

このメソッドは3つの引数をとります:文字列、int、およびDateTimeをとり、intを返す関数です。たとえば:

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

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

3

その後OnGenerateValueの実装では、あなたがのparamのを確認することができますデリゲートに

int GetCachedValue(string key, GenerateValue functionToCall); 

を使用するようにGetCachedValueを定義する方法のためmethodToGetFoo

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

をデリゲートを作成します。

2

Hereは、私が商業プロジェクトのためにやったようにもう少し先に進むことができる簡単なものです。私の場合は

は、このWebサービス呼び出しをキャッシュすることだった、とのようなものを使用した:System.Actionとラムダ式(anonimous法)を用いて

WebService ws = new WebService(); 
var result = ws.Call(x => x.Foo("bar", 1)); // x is the ws instance 
7

を。たとえば、

public void myMethod(int integer){ 

    //Do something 

} 

public void passFunction(System.Action methodWithParameters){ 

    //Invoke 
    methodWithParameters(); 

} 

//... 

//Pass anonimous method using lambda expression 
passFunction(() => myMethod(1234)); 
関連する問題