c# task covariance

c# - ¿Por qué la Tarea<T> no es covariante?



task covariance (2)

class ResultBase {} class Result : ResultBase {} Task<ResultBase> GetResult() { return Task.FromResult(new Result()); }

El compilador me dice que no puede convertir implícitamente la Task<Result> a la Task<ResultBase> . ¿Alguien puede explicar por qué es esto? Hubiera esperado que la covarianza me permitiera escribir el código de esta manera.


Me doy cuenta de que llego tarde a la fiesta, pero aquí hay un método de extensión que he estado usando para dar cuenta de esta característica que falta:

/// <summary> /// Casts the result type of the input task as if it were covariant /// </summary> /// <typeparam name="T">The original result type of the task</typeparam> /// <typeparam name="TResult">The covariant type to return</typeparam> /// <param name="task">The target task to cast</param> [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Task<TResult> AsTask<T, TResult>(this Task<T> task) where T : TResult where TResult : class { return task.ContinueWith(t => t.Result as TResult); }

De esta manera puedes hacer:

class ResultBase {} class Result : ResultBase {} Task<ResultBase> GetResult() { return Task.FromResult(new Result()).AsTask<Result, ResultBase>(); }


Según alguien que puede estar al tanto ...

La justificación es que la ventaja de la covarianza se ve compensada por la desventaja del desorden (es decir, todos tendrían que tomar una decisión sobre si usar Task o ITask en cada lugar de su código).

Me parece que no hay una motivación muy convincente de ninguna manera. ITask<out T> requeriría muchas sobrecargas nuevas, probablemente un poco ocultas (no puedo dar fe de cómo se implementa la clase base real o cuán especial se compara con una implementación ingenua) pero mucho más en forma de estos métodos de extensión tipo linq .

Alguien más hizo un buen punto: el tiempo se gastaría mejor haciendo que la class covariante y contravariante. No sé lo difícil que sería, pero eso me parece un mejor uso del tiempo.

Por otro lado, alguien mencionó que sería genial tener un yield return real como característica disponible en un método async . Quiero decir, sin juego de manos.