Skip to content

[API Proposal]: Task<T>.CastUp #89778

Description

@alrz

Background and motivation

Task does not support covariant type args. This would be similar to ImmutableArray<T>.CastUp.

The current workaround is to simply await the task or use ContinueWith to cast.

API Proposal

public class Task<T>
{
+     public static Task<T> CastUp<TDerived>(Task<TDerived> task) where TDerived : class?, T;
}

public struct ValueTask<T>
{
+     public static ValueTask<T> CastUp<TDerived>(ValueTask<TDerived> task) where TDerived : class?, T;
}

API Usage

Task<string> task1 = e;
Task<object> task2 = Task<object>.CastUp(task);

Alternative Designs

No response

Risks

No response

Activity

  1. added
    api-suggestionEarly API idea and discussion, it is NOT ready for implementation
    on Aug 1, 2023
  2. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Aug 1, 2023
  3. huoyaoyuan commented on Aug 2, 2023

    @huoyaoyuan
    Member

    A covariant interface may be useful for Task, but for ValueTask a CastUp may help better.

  4. added
    needs-further-triageIssue has been initially triaged, but needs deeper consideration or reconsideration
    and removed
    untriagedNew issue has not been triaged by the area owner
    on Aug 8, 2023
  5. added this to the Future milestone on Aug 8, 2023
  6. ericstj commented on Aug 8, 2023

    @ericstj
    Member
  7. added
    api-ready-for-reviewAPI is ready for review, it is NOT ready for implementation
    and removed
    api-suggestionEarly API idea and discussion, it is NOT ready for implementation
    needs-further-triageIssue has been initially triaged, but needs deeper consideration or reconsideration
    on Jul 11, 2026
  8. bartonjs commented on Sep 8, 2026

    @bartonjs
    Member

    Video

    Looks good as proposed.

    public partial class Task<T>
    {
        public static Task<T> CastUp<TDerived>(Task<TDerived> task) where TDerived : class?, T;
    }
    
    public partial struct ValueTask<T>
    {
        public static ValueTask<T> CastUp<TDerived>(ValueTask<TDerived> task) where TDerived : class?, T;
    }
  9. added
    api-approvedAPI was approved in API review, it can be implemented
    and removed
    api-ready-for-reviewAPI is ready for review, it is NOT ready for implementation
    on Sep 8, 2026
  10. added
    in-prThere is an active PR which will close this issue when it is merged
    on Nov 3, 2026
  11. hez2010 commented on Nov 3, 2026

    @hez2010
    Contributor

    We now have another motivating case that can be greatly helped by target-type generic inference. cc: @MadsTorgersen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-approvedAPI was approved in API review, it can be implementedarea-System.Threading.Tasksin-prThere is an active PR which will close this issue when it is merged

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions