In the sample code (it does not compile because of the invalid if check) below I need to figure out if returnValue is a "Task of TResult" or a Task or another type. If it's Task of TResult I can access and log the Result property,if it's a Task, there is no return value and I log "[Task]", if it's neither of these two then I can directly log the return value or log a ["null"]
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);
}
I want to determine if returnValue is a Task or Task of TResult and then take if its the latter, I need to extract the appropriate value from the Result. One idea I have is checking the IsGenericType property, but I am not sure if that will work always.
There may be a cleaner way, but this works and you can build on it. "as" will check the type or base type is a task, then you can inspect the type to see if it has generic type arguments or not. Because it's dynamic, the check for Result being a property is done at runtime instead of compile time.
static void outType(object returnValue)
{
dynamic task = returnValue as Task;
if ( task != null )
{
var gargs = returnValue.GetType().GenericTypeArguments;
if (gargs.Count() == 0)
{
Console.WriteLine("Task");
}
else
{
var result = task.IsCompleted ? task.Result : "[Not Complete]";
Console.WriteLine("Task<{0}> : {1}", gargs[0].Name, result);
}
}
}
Despite Eric Lippert mentioned that you should not fetch Task.Result, there are a few questions to answer:
How to check if an object is a generic type
obj.GetType().IsGenericType
Whether it's Task<TResult>
obj.GetType().GetGenericTypeDefinition() == typeof(Task<>)
How to access a generic property value
obj.GetType().GetProperty("Result").GetValue(obj) // This value could be null
I feel like either none of the preceding answers clearly answered the question being asked, or I rather missed the mark on the intent of the question.
What I interpreted from the question was:
"How do I tell if 'returnValue' is of Type 'Task', 'Task<>', or something else?
This test code may be used to determine this:
Task voidTask = new Task(() => { return; });
Task<object> valTask = new Task<object>(() => { return null; });
Type voidTaskType = voidTask.GetType();
Type valTaskType = valTask.GetType();
Console.WriteLine($"voidTaskType is Task : {voidTask is Task}");
Console.WriteLine($"valTaskType is Task : {valTask is Task}");
Console.WriteLine($"voidTaskType.IsGenericType : {voidTaskType.IsGenericType}");
Console.WriteLine($"valTaskType.IsGenericType : {valTaskType.IsGenericType}");
The results are as follows:
voidTaskType is Task : True
valTaskType is Task : True
voidTaskType.IsGenericType : False
valTaskType.IsGenericType : True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With