具有相似主体的通用方法和非通用方法

5
我有一个名为ExecuteAsyncServiceRequest的方法,它有一个重载版本。你会注意到两个方法的主体是相似的。我在想是否有更简洁的方法来编写这些方法?具体来说,不必在方法主体中重复自己。
提前感谢您的帮助!
    /// <summary>
    /// Executes an async service request which returns a response of type TResponse
    /// </summary>
    /// <param name="execute">The service request to execute</param>
    /// <param name="success">Callback when the service request is successful</param>
    /// <param name="failure">Callback when the service request fails</param>
    /// <typeparam name="TResponse">Type of the expected ServiceResult returned from the async request</typeparam>
    protected async void ExecuteAsyncServiceRequest<TResponse>(Func<Task<ServiceResult<TResponse>>> execute,
                                                            Action<TResponse> success,
                                                            Action<string> failure)
    {
        ServiceResult<TResponse> result = await execute();

        if (result.ResultCode == ServiceResult.ServiceResultCode.Failed)
            failure(result.FailureDetails);

        success(result.Response);    
    }

    /// <summary>
    /// Executes an async service request
    /// </summary>
    /// <param name="execute">The service request to execute</param>
    /// <param name="success">Callback when the service request is successful</param>
    /// <param name="failure">Callback when the service request fails</param>       
    protected async void ExecuteAsyncServiceRequest(Func<Task<ServiceResult>> execute,
                                                    Action success,
                                                    Action <string> failure)
    {
        ServiceResult result = await execute();

        if (result.ResultCode == ServiceResult.ServiceResultCode.Failed)
            failure(result.FailureDetails);

        success();
    }

请提供您尝试过的内容以及不起作用的原因的解释。 - SneakyTactician
@SneakyTactician 这段代码运行良好,但我发现自己在问一个问题:“如何优化这个代码?它能被优化吗?”也许答案很简单,就是“不能”? - Jon Scalet
如果ServiceResult和TResponse继承自同一类或使用相同的接口,则可以通用地组合这些方法。如果不是,请参见Stephan的答案。 - SneakyTactician
1个回答

4

不幸的是,这是.NET本身类型系统的限制,具体来说,void不是一种类型。

在更多受函数式编程影响的语言中(相对于传统面向对象编程),通常没有void的概念;取而代之的是存在一个特殊类型(通常称为unit),它只有一个值。类似这样:

public sealed class Unit {
  private Unit() { }
  public static Unit Instance { get; } = new Unit();
}

您可以使用类似的代码,但是是否值得完全取决于您自己:

protected async void ExecuteAsyncServiceRequest(Func<Task<ServiceResult>> execute,
                                                Action success,
                                                Action <string> failure) =>
    ExecuteAsyncServiceRequest(
        async () => new ServiceResult<Unit>(await execute(), Unit.Instance),
        _ => success(),
        failure);

假设 ServiceResult<T> 可以有一个(可能是internal)构造函数,该构造函数将 ServiceResult 作为参数并复制除了实际的“结果”外的所有属性,实际的“结果”则从第二个构造函数参数中复制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接