2017-08-10 117 views
1

我有一个名为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(); 
    } 
+0

请提供一个你已经尝试了什么,以及什么不起作用的解释。 – SneakyTactician

+0

@SneakyTactician代码运行良好,但我发现自己提出了这样一个问题:“如何优化?可以优化吗?”。也许答案只是“不”? –

+0

如果ServiceResult和TResponse从同一个类继承或使用相同的接口,那么您可以一般地组合这些方法。如果没有,请参阅斯蒂芬的回答。 – SneakyTactician

回答

1

号不幸的是,这是由于在.NET本身的类型系统的限制 - 具体地,void不是一个类型。

具有更多功能影响力的语言(与传统OOP相反)往往不具有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作为参数,并复制除了从第二个构造函数参数复制的实际“结果”之外的所有属性。

+0

好东西,谢谢你们两位! –