Mi piace molto lavorare con la programmazione asincrona C# 5.0. Tuttavia, ci sono alcuni punti in cui l'aggiornamento del vecchio codice per essere coerente con il modello TAP sta causando problemi.È possibile/deve eseguire l'attività <TResult> in un C# 5.0 attendibile che è covariante in TResult?
Ecco uno di loro - io non so esattamente il motivo per cui Task<TResult>
non è covariante nel TResult, ma è causando problemi per me, quando si cerca di aggiornare un'interfaccia covariante di passare da un sincrono a un modello asincrono:
vecchio codice:
public interface IInitializable<out T> // ** out generic modifier **
{
/// <summary>
/// Boolean to indicate if class is ready
/// </summary>
bool IsInitialized { get; }
/// <summary>
/// Calls for instance to be initialized using current parameters
/// Driver initialization can be done in the default constructor if desired
/// </summary>
T Initialize();
}
Nuovo codice (non verrà compilato):
public interface IAsyncInitializable<out T> // ** out generic modifier...broken **
{
/// <summary>
/// Boolean to indicate if class is ready
/// </summary>
bool IsInitialized { get; }
/// <summary>
/// Calls for instance to be initialized using current parameters
/// Driver initialization can be done in the default constructor if desired
/// </summary>
Task<T> InitializeAsync(); // ** breaks because Task<TResult> is invariant in TResult **
}
è che c'è un modo ragionevole intorno a questo senza mo difendendo le mie API troppo drasticamente? (Bonus: perché Task non è covariante?). Non esiste un'interfaccia IAwaitable, ma suppongo che potrei crearne uno e creare un metodo di estensione che converta in un oggetto task avvolto, covariante e avvincente. O sto sbagliando?
BTW, anche se 'Task' era un'interfaccia covariante, il codice sarebbe essere compilato. La versione corretta sarebbe 'Task InitializeAsync();' (senza il modificatore 'out' su quella linea). –
svick
Un punto eccellente. L'ho corretto in VS, ma ho dimenticato di modificare SO. –