简体   繁体   中英

How to cast object type to Task<T> type?

How can I cast an object instance of type object to type Task<T> ?

I store a Task<T> reference in a variable of type object and need to cast it back to Task<T> because the method needs to return type Task<T> .

Try using the Task.FromResult<TResult> method . From MSDN:

T obj = new T();
Task<T> a = Task.FromResult(obj);

If T is known at the time of casting, there should be no problem doing:

Task<T> myTask = (Task<T>)myObject;

Example: https://dotnetfiddle.net/oOg4E8

You can use the as operator. If the object is of type Task<T> you get a correct references. Otherwise you get null .

var task = obj as Task<T>;

If the object you have stored is actually the Task<T> you can just use a direct cast.

var task = (Task<X>)obj;

If you have the object result, unwrapped, and you need a task result from the instance, you can use Task.FromResult(X) which return a completed Task<T> of type X .

Given:

  • The variable is defined as object
  • The value is type Task<T1>
  • T1 is not available at compile time.
  • You need to cast the object to Task<T2> where T1 : T2 , but not T1 == T2 (likely T2 is an interface implemented by T1 ).

The other answers will not work when T1 != T2 .

This extension method works well for me to preform the cast.

public static class TaskExtensions
{
    public static Task<T> CastTask<T>(this object taskObj)
    {
        var taskType = taskObj.GetType();
        if (!taskType.IsSubClassOfGeneric(typeof(Task<>)))
            throw new ArgumentException($"{taskType.FullName} is not of type Task<>");
        var resultType = taskType.GenericTypeArguments.First();
        var castTaskMethodGeneric = typeof(TaskExtensions)
            .GetMethod("CastTaskInner", BindingFlags.Static | BindingFlags.Public);
        var castTaskMethod = castTaskMethodGeneric.MakeGenericMethod(
            new Type[] { resultType, typeof(T) });
        var objCastTask = castTaskMethod.Invoke(null, new object[] { taskObj });
        return objCastTask as Task<T>;
    }

    public static async Task<TResult> CastTaskInner<T, TResult>(Task<T> task)
    {
        var t = await task;
        var tObj = (object)t;
        return (TResult)tObj;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM