Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

455
Vistas
¿Por qué Task<T> no es covariante?
class ResultBase {} class Result : ResultBase {} Task<ResultBase> GetResult() { return Task.FromResult(new Result()); }

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

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

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

La justificación es que la ventaja de la covarianza se ve superada 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 bastante ocultas (no puedo dar fe de cómo se implementa la clase base real o qué tan especial es en comparación con una implementación ingenua), pero mucho más en forma de estos métodos de extensión similares linq .

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

Por otro lado, alguien mencionó que sería genial tener una función similar a la de yield return real disponible en un método async . Quiero decir, sin juegos de manos.

over 4 years ago · Santiago Trujillo Denunciar

0

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

 /// <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 async Task<TResult> AsTask<T, TResult>(this Task<T> task) where T : TResult where TResult : class { return await task; }

De esta manera solo puedes hacer:

 class ResultBase {} class Result : ResultBase {} Task<Result> GetResultAsync() => ...; // Some async code that returns Result Task<ResultBase> GetResultBaseAsync() { return GetResultAsync().AsTask<Result, ResultBase>(); }
over 4 years ago · Santiago Trujillo Denunciar

0

He tenido éxito con el paquete MorseCode.ITask NuGet . En este punto, es bastante estable (sin actualizaciones en algunos años), pero fue trivial de instalar y lo único que tenía que hacer para traducir de una tarea de TI a una tarea era llamar a .AsTask() (y el método de extensión inversa también se incluye con el paquete).

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda