检查Object是否为Task或Task <TResult>

Sus*_*ant 3 .net c# task async-await

在下面的示例代码中(因为检查无效而无法编译)我需要弄清楚returnValue是"TResult的任务"还是任务或其他类型.如果它是TResult的任务我可以访问并记录Result属性,如果它是一个Task,则没有返回值,我记录"[Task]",如果它们都不是这两个那么我可以直接记录返回值或记录一个["空值"]

public void LogReturnValue(obj returnValue)
{
   var valueToLog = "";
   if(returnValue is Task)
   {
       valueToLog = "[Task]";
   } else if(returnValue is Task<T>)
   {
     valueToLog = returnValue.Result;
   } 
   else 
   {
     valueToLog = returnValue ?? "[null]"
   }
   this.logger.Log(valueToLog);
}
Run Code Online (Sandbox Code Playgroud)

我想确定returnValue是否是TResult的任务或任务,然后如果是后者,我需要从结果中提取适当的值.我有一个想法是检查IsGenericType属性,但我不确定它是否会始终有效.

qxg*_*qxg 9

尽管Eric Lippert提到你不应该获取Task.Result,但仍有几个问题要回答:

  1. 如何检查对象是否是泛型类型

    obj.GetType().IsGenericType
    
    Run Code Online (Sandbox Code Playgroud)
  2. 是否是任务<TResult>

    obj.GetType().GetGenericTypeDefinition() == typeof(Task<>)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 如何访问通用属性值

    obj.GetType().GetProperty("Result").GetValue(obj) // This value could be null
    
    Run Code Online (Sandbox Code Playgroud)

  • 在有人被咬之前——从表面上看,你会得到任务,但第二次检查会失败,你会得到结果。文本表示是“System.Threading.Tasks.VoidTaskResult”。 (2认同)
  • 注意:你_不能_依赖 #2 来确定它是 Task&lt;TResult&gt;,取决于运行时,它可能是 `System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[TResult,TStateMachine]` (2认同)