Naprawdę lubię pracować z programowaniem asynchronicznym C# 5.0. Jest jednak kilka miejsc, w których aktualizacja starego kodu, który jest zgodny z modelem TAP, sprawia mi problemy.Może/powinien Zadanie <TResult> być zapakowane w C# 5.0, co jest kowariantne w TResult?
Oto jeden z nich - nie jestem pewien dokładnie dlaczego Task<TResult>
nie kowariantna w TResult, ale to powoduje problemy dla mnie podczas próby aktualizacji kowariantna interfejs przenieść z synchronicznym do asychronous wzoru:
stary kod:
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();
}
Nowy kod (nie będzie skompilować):
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 **
}
Czy istnieje rozsądny sposób obejść bez MO zbyt drastycznie ograniczasz moje interfejsy API? (Bonus: dlaczego Zadanie nie jest kowariantne?). Nie ma interfejsu IAwaitable, ale przypuszczam, że mógłbym go stworzyć i stworzyć metodę rozszerzenia, która przekształca się w owinięty, kowariantny, trwały obiekt zadania. Czy robię to źle?
BTW, nawet jeśli 'Task' był kowariantna interfejs, Twój kod nie skompilować. Poprawna wersja to 'Task InitializeAsync();' (bez modyfikatora 'out' w tym wierszu). –
svick
Doskonały punkt. Poprawiłem to w VS, ale zapomniałem edytować SO. –