問題
我有以下代碼:
Action function = async () => await Task.CompletedTask;
這段代碼的問題在于,即使從技術上講它是一個異步委托(可以是awaited),我也不能等待它。換句話說,上面可以等價地寫成
Func<Task> function = async () => await Task.CompletedTask;
后者可以等待,而前者不能,即使這是內部相同的方法。顯然,這是一個人為的例子,在我的用例中,更復雜的代碼駐留在更復雜的代碼庫中,并且不容易發現所有的誤用。
問題
我可以function在運行時檢查實際型別并將其轉換為正確的型別嗎?
我試過的
function下面的代碼只有在我宣告為Func<Task>(也不能像我預期的那樣作業)時才會拋出
Action function = async () => await Task.CompletedTask;
if (function.GetMethodInfo().ReturnType.IsEquivalentTo(typeof(Task)))
{
throw new Exception();
}
下面的代碼甚至無法編譯
Action function = async () => await Task.CompletedTask;
if (function is Func<Task> func)
{
}
uj5u.com熱心網友回復:
即使這是內部相同的方法。
不過,它不是。
當然,委托被編譯成一個方法,但該方法的型別取決于它分配給的內容。如果它被分配給Func<Task>,那么它是一個Task-returning 方法。如果它被分配給Action,那么它是一個void-returning 方法。
所以,check the actual type of function at runtime是行不通的;運行時為時已晚。
相反,您需要編譯時檢查。好訊息:有一些分析器應該能捕捉到這一點。例如,ReSharper或Roslyn 分析器。
uj5u.com熱心網友回復:
在運行時檢查委托的型別
打電話.GetType()有用嗎?
下面的代碼甚至無法編譯
Action function = async () => await Task.CompletedTask; if (function is Func<Task> func) { }
這將編譯并運行
Action function = async () => await Task.CompletedTask;
if (function.GetType() == typeof(Func<Task>))
{
// not reachable
}
在運行時
Action function1 = async () => await Task.CompletedTask;
Func<Task> function2 = async () => await Task.CompletedTask;
var b = function1.GetType() == typeof(Action); // true
b = function1.GetType() == typeof(Func<Task>); // false
b = function2.GetType() == typeof(Action); // false
b = function2.GetType() == typeof(Func<Task>); // true
一些有用的擴展
public static bool IsAction(this MulticastDelegate @delegate) =>
@delegate.GetType() == typeof(Action);
public static bool ReturnsTask(this MulticastDelegate @delegate) =>
@delegate.GetType() == typeof(Func<Task>);
public static bool ReturnsTask<T>(this MulticastDelegate @delegate) =>
@delegate.GetType() == typeof(Func<Task<T>>);
示例用法
var function = async () => await Task.FromResult(true);
var b = function.IsAction(); // false
b = function.ReturnsTask(); // false
b = function.ReturnsTask<string>(); // false
b = function.ReturnsTask<bool>(); // true
if (b)
{
// possible to await
await function?.Invoke();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/513894.html
