【问题标题】: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 只检查 HttpStatus2. HttpCaller 以复杂的Predicate 调用。我对么?如果我是,为什么不使用两种方法HttpCaller:一种使用预期的HttpStatusarg,另一种使用Predicatearg?
  • 所以 HttpCaller 方法处理许多不同的场景,因此接受许多不同的谓词,其中一些只测试特定的 http 状态......所以拥有多个方法没有意义做同样的事情

标签: c# functional-programming delegates predicate


【解决方案1】:

接下来的两种方法可以用来去掉所有只检查HttpStatusCode的谓词。


1。创建一个为给定的HttpStatusCode 创建Predicate 的方法:

public static Predicate<HttpResponseData> CreatePredicateByHttpStatusCode(HttpStatusCode status)
{
    return r => r.StatusCode == status;
}

然后当你需要一个只检查给定HttpStatusCodePredicate时使用这个方法:

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 =&gt; r.StatusCode == HttpStatusCode.OK,然后您甚至不需要@ 987654337@方法:)
猜你喜欢
  • 2015-07-18
  • 2021-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
相关资源
最近更新 更多