class ResultBase {}
class Result : ResultBase {}
Task<ResultBase> GetResult() {
return Task.FromResult(new Result());
}
コンパイラーは、Task<Result>
をTask<ResultBase>
に暗黙的に変換できないことを教えてくれます。これがなぜなのか誰かが説明できますか?この方法でコードを記述できるようにするために、共分散を期待していました。
知っている人 ...によると.
正当化は、共分散の利点が乱雑さの欠点に勝るということです(つまり、誰もがコードのすべての場所でTaskまたはITaskを使用するかどうかの決定をしなければならないでしょう)。
どちらにしても、非常に説得力のある動機はないように思えます。 ITask<out T>
は多くの新しいオーバーロードを必要としますが、おそらく実際にはかなりの部分(実際の基本クラスがどのように実装されているか、または単純な実装と比較してどのように特別であるかについては証明できません)ですが、これらの形式でさらに多くのlinq
のような拡張メソッド。
他の誰かが良い点を作りました-class
esを共変と反変にするのに費やす時間はもっと良いでしょう。それがどれほど難しいかはわかりませんが、それは私にとって時間のより良い使い方のように思えます。
一方、誰かが本当のyield return
のような機能はasync
メソッドで使用できます。つまり、手抜きなし。
私はパーティーに遅れていることに気づきましたが、この欠けている機能を説明するために私が使用してきた拡張メソッドは次のとおりです。
/// <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);
}
このようにしてあなたはただ行うことができます:
class ResultBase {}
class Result : ResultBase {}
Task<ResultBase> GetResult()
{
return Task.FromResult(new Result()).AsTask<Result, ResultBase>();
}