2016-11-10 20 views
2

我的目標是將任何具有返回類型的函數傳遞給我的Execute方法,並對其結果進行序列化和存儲。下面是我想要做的事情的一個粗略的想法,顯然不會編譯,但希望它能夠實現這個想法。我想我也應該能夠遞歸地處理嵌套的任務。思考?是否可以確定一個方法是否返回一個Task並等待它呢?

public static TResult Execute<TResult>(Func<TResult> method) 
     where TResult : class 
    { 

     var result = method(); 
     if(result is Task) 
     { 
      var taskResult = await result; 
      StoreResult(taskResult); 
     } 
     else 
     { 
      StoreResult(result); 
     } 
    } 
+5

創建兩個重載,一個這需要一個'Func鍵<任務>'和其他'Func '。 – Lee

回答

1

我同意李的評論,認爲有一個單獨的Func<Task<TResult>>超載是正確的解決方案。

但如果你真的想這樣做,使用一個超載,你可以使用反射和dynamic,使這項工作:

public async static Task Execute<TResult>(Func<TResult> method) where TResult : class 
{ 
    var result = method(); 

    if (typeof(TResult).IsGenericType 
     && typeof(TResult).GetGenericTypeDefinition() == typeof(Task<>)) 
    { 
     var taskResult = await (dynamic)result; 
     StoreResult(taskResult); 
    } 
    else 
    { 
     StoreResult(result); 
    } 
} 
+0

謝謝!我想我會用超載來做到這一點,但這正是我所期待的。 – Mike

2

下面是一個人爲的例子,說明如何做到這一點。

我會質疑這種模式的智慧。我寧願總是返回一個任務,即使任務並不總是需要的。 Task.FromResult()的開銷通常可以忽略不計。

public async Task<T> Foo<T>() 
{ 
    var mightBeATask = Bar<T>(); 
    var task = mightBeATask as Task<T>; 

    if(task != null) 
    { 
     return await task; 
    } 

    return (T)mightBeATask; 
} 

private object Bar<T>() 
{ 
    return Task.FromResult(default(T)); 
} 
相關問題