将一个函数传递给另一个函数
本文关键字:函数 另一个 一个 | 更新日期: 2023-09-27 18:29:35
我正在C#中编写一个HTTP包装类对象,我想让主方法能够接收一个函数作为参数,然后在POST/GET返回的源HTML上执行它。
例如,我可能想传递一个函数,该函数检查cookie的标头,并且只有在找到cookie时才返回true,或者传递一个正则表达式函数,检查内容的源。
我知道在PHP或JS中,我可以很容易地将函数作为参数传递,但我不确定如何在不创建与我想要使用的函数匹配的委托的情况下进行传递。
我希望代码尽可能"通用",这样它就可以接收任何函数,例如伪代码就像
public bool MakeHTTPRequest(string url, object possiblefunction)
{
make HTTP request
if status == 200
{
string response = getresponse
if(object is function){
call object
}
}
}
因此,函数可能会被传入,也可能不会被传入,或者我可以用它设置一个全局属性。然后我需要检查一个函数是否存在,如果存在,就执行它。
这个函数可以是任何东西,我想对代码进行未来验证,这样它就可以在未来处理任何可能传递给它的函数。
任何帮助都将不胜感激。
感谢
使用Func
或Action
(或DavidN提到的Predicate
)来指定作为参数传递到MakeHTTPRequest
方法中的委托契约。
public bool MakeHTTPRequest(string url, Action possiblefunction)
{
make HTTP request
if status == 200
{
string response = getresponse
if(possiblefunction != null){
possiblefunction();
}
}
}
如果您的"函数"返回值/结果,则使用Func。。(其中T是预期的返回类型)。。。例如CCD_ 5。
如果"函数"需要参数,则指定所需的参数类型。下面是一些例子:
Func<string,float,int>
-一个委托,它需要字符串和浮点参数,并返回一个int结果
Action
-一个不接受参数且不返回值的委托
Action<string,float>
-一个不返回值(void)的委托,需要一个字符串和float作为参数。
- http://www.blackwasp.co.uk/FuncAction.aspx
- 函数与动作与谓词
如果您试图将"响应"传递回possiblefunction
,请执行以下操作。
public bool MakeHTTPRequest(string url, Action<string> possiblefunction)
{
make HTTP request
if status == 200
{
string response = getresponse
if(possiblefunction != null){
possiblefunction(response);
}
}
}
根据您给出的示例,您真正想要的似乎是传递一组验证器,以确定HTTP响应是否符合某些标准。您的方法返回bool这一事实似乎进一步证实了这一点。
Predicate<T>
,或者实际上是一组谓词,应该封装您传入的条件规则,以确定请求是否有效。
Predicate<T>
的签名是bool Predicate<T>(T t)
,这意味着它采用某种类型并产生布尔
使用一组谓词,并确保它们都通过,似乎是一种非常经得起未来考验的方法,可以实现
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..任意数量]值的方法,因此以下所有调用都可以工作:
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);