2017-08-10 177 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

好東西,謝謝你們兩位! –