简体   繁体   English

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

[英]Passing a Function (with parameters) as a parameter?

I want to create a generic to which I can pass a function as a parameter, however this function may include parameters itself so...我想创建一个泛型,我可以将一个函数作为参数传递给它,但是这个函数可能包含参数本身,所以......

int foo = GetCachedValue("LastFoo", methodToGetFoo)

Such that:这样:

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

Essentially I want to have a method that will check the cache for a value, otherwise will generate the value based on the passed in method.本质上,我想要一个方法来检查缓存中的值,否则将根据传入的方法生成值。

Thoughts?想法?

It sounds like you want a Func<T> :听起来你想要一个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;
}

The caller can then wrap this in many ways;然后调用者可以通过多种方式包装它; for simple functions:对于简单的功能:

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

or where arguments are involved, a closure:或者在涉及参数的地方,一个闭包:

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

Use System.Action and a lambda expression (anonymous method).使用System.Action和 lambda 表达式(匿名方法)。 For example:例如:

public void myMethod(int integer) {     
    // Do something
}

public void passFunction(System.Action methodWithParameters) {
    // Invoke
    methodWithParameters();
}

// ...

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

You can create your own delegate, but in C# 3.0 you may find it more convenient to use the built-in Func<T> delegate family to solve this problem.您可以创建自己的委托,但在 C# 3.0 中,您可能会发现使用内置的Func<T>委托系列来解决这个问题更方便。 Example:例子:

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
}

This method will take three arguments: a string, an int, and a function that takes a DateTime and returns an int.此方法将采用三个参数:一个字符串、一个 int 和一个接受 DateTime 并返回一个 int 的函数。 For example:例如:

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

Different Func<T, U, V...> etc. types exist in the framework to accommodate methods with different amounts of arguments.框架中存在不同的Func<T, U, V...>等类型,以适应具有不同数量参数的方法。

Create a delegate for the method methodToGetFoomethodToGetFoo方法创建一个委托

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

Define GetCachedValue to use the delegate定义 GetCachedValue 以使用委托

int GetCachedValue(string key, GenerateValue functionToCall);

Then in the implementation of OnGenerateValue you can check the param's.然后在 OnGenerateValue 的实现中,您可以检查参数。

Here is something simple I started that can be taken a bit further (as I did for a commercial project). 是我开始的一些简单的事情,可以更进一步(就像我为商业项目所做的那样)。

In my case this was to cache web service calls, and was used something like:在我的情况下,这是缓存 Web 服务调用,并使用了类似的东西:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM