2012-08-30 5 views
11

私はC#5.0非同期プログラミングの作業を本当に楽しんでいます。しかし、TAPモデルと一貫性を持たせるために古いコードを更新することが私にとって問題を引き起こしている場所はいくつかあります。タスク<TResult>はTResultで共変なC#5.0待ち時間にラップすることができますか?

:私はTask<TResult>はTResultに共変されていない正確な理由はわからないが、非同期パターンに同期から移動するために、共変のインターフェイスを更新しようとしたとき、それは私のために問題を引き起こしている -

ここではそのうちの一つです旧コード:

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(); 
} 

新しいコード(コンパイルされません):

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 ** 
} 

は、合理的な方法は、MOせずにこの問題を回避ありです私のAPIをあまりにも劇的に変えてしまいましたか? (ボーナス:なぜタスクは共変しないのですか?) IAwaitableインターフェイスはありませんが、私はそれを作って、ラップされた共変のawiatableタスクオブジェクトに変換する拡張メソッドを作成することができます。それとも間違っているのですか?

+2

ところで、 'Task'は共変のインターフェイスであっても、あなたのコードがコンパイルされないでしょう。正しいバージョンは 'Task InitializeAsync();'(その行に 'out'修飾子なし)です。 – svick

+0

優れた点。私はVSでそれを修正したが、SOを編集するのを忘れてしまった。 –

答えて

12

Task<T>は、クラスであるためTには共変できません。インタフェースと代理人だけが一般的な分散を持つことができます。

ラッピングを行う価値があるかどうかは、プロジェクト内の共分散をどのくらい使うかによって決まります。私はあなたがすべてのラッピングとアンラップが時間の経過とともに混乱しているのを見つけたと思っています。正直なところ、でもの共分散を取り除くだけの悪さはありません。

+0

アドバイスをいただきありがとうございます!あなたのEduasync TaskAwaiter(T)を使ってIAwaitable(out TResult)を実装しました。別のインターフェイスを使用することは、可読性/ユーザビリティを損なうものではありません。そして、素晴らしい点は:クラスとジェネリックな分散...私の間違いを@Jon Skeetが指摘してくれて光栄です:)。 ITask(out T)はまったく駄目です。私はStephen Clearyのコメント(http://stackoverflow.com/questions/8407227/async-generic-delegate-in-c-sharp-5-0)を参照していますが、WinRTの相互運用性の互換性は、使用するための正当性としては少し不満です具体的なタイプ。 –

+1

@DavidCuccia:Stephen Toubのブログで、待っている人にはコンテキストを伝播することをお読みください。 –

+0

@JonSkeet - なぜフレームワーク開発者が 'ITask 'を追加せず、クラスのみを実装したのか? –

4

私はITaskインターフェイスのasyncキーワードのコンパイラサポートを含めて、マイクロソフトの主要な見落としではないと考えています。幸運にも、この制限を回避するのは難しいことではありません。

私は、共存可能なITask<out TResult>インターフェイスを実装しました。その使用法はかなり簡単です。詳しい情報はで見つけることができます

https://github.com/jam40jeff/ITask

関連する問題