可以由调用者自定义的通用谓词?
Posted
技术标签:
【中文标题】可以由调用者自定义的通用谓词?【英文标题】:A generic predicate which can be customized by caller? 【发布时间】:2020-10-14 05:33:23 【问题描述】:我有一堆这样定义的谓词,每个谓词检查不同的 http 状态代码:
readonly Predicate<HttpResponseData> createdHttpStatusPredicate = (HttpResponseData responseData) =>
return responseData.StatusCode == HttpStatusCode.Created;
;
readonly Predicate<HttpResponseData> okHttpStatusPredicate = (HttpResponseData responseData) =>
return responseData.StatusCode == HttpStatusCode.OK;
;
...
我像这样将它们传递到以下方法中(代码已经稍微简化以删除不相关的细节):
public static async Task<HttpResponseData> HttpCaller(HttpMethod requestMethod, Predicate<HttpResponseData> predicate)
HttpResponseData response = await SendHttpRequest(requestMethod);
if (predicate(response) == true)
return response;
else
return null;
这是一个将一个谓词发送到上述方法的示例调用:
HttpResponseData data = await HttpRequestUtils.HttpCaller(HttpMethod.Post, createdHttpStatusPredicate);
我想知道,我是否可以将所有谓词组合到某个通用谓词中,或者以某种方式指定要在我调用 HttpCaller
时在谓词中查找的 http 状态?
是的,我知道上面的例子没有多大意义,因为我可以直接将我正在寻找的 http 状态传递给 HttpCaller
而无需通过谓词,但在我的情况下,HttpCaller
可以接收我的复杂的谓词也作为输入,基于从哪里调用HttpCaller
【问题讨论】:
如果我对问题的理解正确,您有两种情况:1.HttpCaller
被调用,Predicate
只检查 HttpStatus
; 2. HttpCaller
以复杂的Predicate
调用。我对么?如果我是,为什么不使用两种方法HttpCaller
:一种使用预期的HttpStatus
arg,另一种使用Predicate
arg?
所以 HttpCaller 方法处理许多不同的场景,因此接受许多不同的谓词,其中一些只测试特定的 http 状态......所以拥有多个方法没有意义做同样的事情
【参考方案1】:
接下来的两种方法可以用来去掉所有只检查HttpStatusCode
的谓词。
1。创建一个为给定的HttpStatusCode
创建Predicate
的方法:
public static Predicate<HttpResponseData> CreatePredicateByHttpStatusCode(HttpStatusCode status)
return r => r.StatusCode == status;
然后当你需要一个只检查给定HttpStatusCode
的Predicate
时使用这个方法:
var result = await HttpCaller(httpMethod, CreatePredicateByHttpStatusCode(HttpStatusCode.OK));
2。创建方法 HttpCaller
的重载,它接受 HttpStatusCode
并且只检查给定的 HttpStatusCode
:
// This is your current method. It accepts a common Predicate that is used
// to check for complex conditions.
public static async Task<HttpResponseData> HttpCaller(HttpMethod requestMethod, Predicate<HttpResponseData> predicate)
HttpResponseData response = await SendHttpRequest(requestMethod);
if (predicate(response) == true)
return response;
else
return null;
// This is a new Method. It accepts HttpStatusCode instead of the Predicate.
// It can be used for checking only for HttpStatusCode.
public static async Task<HttpResponseData> HttpCaller(HttpMethod requestMethod, HttpStatusCode status)
// Here your original method HttpCaller is used.
return await HttpCaller(requestMethod, r => r.StatusCode == status);
当您只需要检查HttpStatusCode
时,可以使用HttpCaller
的重载形式:
var result = await HttpCaller(httpMethod, HttpStatusCode.OK);
【讨论】:
您的第一个解决方案很棒,但是可以进一步减少...在您调用CreatePredicateByHttpStatusCode(HttpStatusCode.OK)
的地方,只需将其替换为r => r.StatusCode == HttpStatusCode.OK
,然后您甚至不需要@ 987654337@方法:)以上是关于可以由调用者自定义的通用谓词?的主要内容,如果未能解决你的问题,请参考以下文章