将函数传递给另一个函数

时间:2013-08-30 12:34:08

标签: c# asp.net http lambda anonymous-function

我正在用C#编写一个HTTP包装器类对象,我想让main方法能够接收函数作为参数,然后在POST / GET返回的源HTML上执行它。

例如,我可能希望传递一个检查cookie标头的函数,只有在找到它时才返回true或者传递一个正则表达式函数来检查一段内容的源。

我知道在PHP或JS中我可以很容易地将函数作为参数传递但是我不知道如何在不创建与我想要使用的函数匹配的委托的情况下去做。

我希望代码尽可能“通用”,以便它可以接收任何函数,例如Pseudocode就像

public bool MakeHTTPRequest(string url, object possiblefunction)
{

   make HTTP request

   if status == 200
   {

    string response = getresponse

    if(object is function){

        call object
    }
  }
}

因此函数可能不会传入OR,或者我可能会使用它设置全局属性。然后我需要检查IF函数是否存在并执行它。

该函数可能是任何东西,我希望将来证明代码,以便它可以处理将来可能传递给它的任何类型的函数。

非常感谢任何帮助。

由于

2 个答案:

答案 0 :(得分:1)

使用{@ 1}}或Func(或DavidN所提及的Action)来指定作为参数传递到Predicate方法的代理人的合同。

MakeHTTPRequest

如果你的“函数”返回一个值/结果,那么使用Func代替..(其中T是预期的返回类型)...例如。 public bool MakeHTTPRequest(string url, Action possiblefunction) { make HTTP request if status == 200 { string response = getresponse if(possiblefunction != null){ possiblefunction(); } } }

如果您的“函数”需要参数,则指定预期的参数类型。所以这里有一些例子:

Func<int> - 一个委托,它需要string和float参数并返回一个int结果

Func<string,float,int> - 不带参数的委托,不返回值

Action - 一个不返回值(void)的委托,并期望一个字符串和float作为参数。

如果您尝试将“响应”传回Action<string,float>,请执行此类操作。

possiblefunction

答案 1 :(得分:0)

根据您给出的示例,您真正想要的是传递一组验证器来确定HTTP响应是否符合某些条件。您的方法返回bool这一事实似乎进一步证实了这一点。

Predicate<T>或实际上是一组Predicates,应该封装您传入的条件规则,以确定请求是否有效。

Predicate<T>的签名是bool Predicate<T>(T t) - 意味着它需要某种类型并生成一个bool

使用谓词数组并确保它们全部通过,似乎是一种非常适合您未来的方式

public bool MakeHTTPRequest(string url, params Predicate<WebResponse>[] validators)
{    
   // make HTTP requrest

   var request = HttpWebRequest.Create(url);
   var response = (HttpWebResponse)request.GetResponse();

   if (response.StatusCode == HttpStatusCode.OK){
        foreach(var validator in validators)
            if (!validator(response))
                return false;
   }

    return true;    
}

诀窍是params关键字允许您调用传递params的[0..any number]值的方法,因此所有以下调用都可以工作:

MakeHTTPRequest("http://stackoverflow.com");
MakeHTTPRequest("http://stackoverflow.com", r => r.Headers.AllKeys.Contains("CookieHeader"));
MakeHTTPRequest("http://stackoverflow.com", r => r.Headers.AllKeys.Contains("CookieHeader"), r => r.ContentLength < 10000);