传递函数(带参数)作为参数?

时间:2009-03-02 21:21:29

标签: c# parameters delegates

我想创建一个可以将函数作为参数传递给它的泛型,但是这个函数可能包含参数本身......

int foo = GetCachedValue("LastFoo", methodToGetFoo)

这样:

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

基本上我想要一个方法来检查缓存中的值,否则将根据传入的方法生成值。

思想?

5 个答案:

答案 0 :(得分:43)

听起来你想要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 :(得分:9)

使用System.Action和lambda表达式(anonimous方法)。例如

    public void myMethod(int integer){

    //Do something

}

public void passFunction(System.Action methodWithParameters){

    //Invoke
    methodWithParameters();

}

//...

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

答案 2 :(得分:4)

您可以创建自己的委托,但在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的函数。例如:

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 :(得分:3)

为方法methodToGetFoo

创建委托
public delegate object GenerateValue(params p);
public event GenerateValue OnGenerateValue;

定义GetCachedValue以使用委托

int GetCachedValue(string key, GenerateValue functionToCall);

然后在OnGenerateValue的实现中,您可以检查参数。

答案 4 :(得分:2)

Here是我开始时的一些简单的事情,可以采取更进一步的措施(正如我为商业项目所做的那样)。

在我的情况下,这是缓存Web服务调用,并使用类似:

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