2012-06-20 9 views
9

私はこの単純なコードを持っている:.NET共分散

public interface IReader<out T> 
{ 
    IEnumerable<T> GetData(); 
} 

このインタフェースは、Tに共変しなければならない、と私はそれをこのように使用しています:Tのための制約を実装するため

private static Func<bool> MakeSynchroFunc<T>(IReader<T> reader) where T : IComposite 
{ 
    return() => Synchronize(reader); 
} 

注意をIComposite。 同期方法は、入力にIReader<IComposite>を取ります

private static bool Synchronize(IReader<IComposite> reader) 
{ 
    // ...... 
} 

コンパイラは、それがT上の制約とIReaderの共分散にもかかわらず、IReader<IComposite>IReader<T>から変換することはできませんと言われます。

私はここで間違っていますか? コンパイラは制約を確認できなければなりません。共分散は私がIReader<T>IReader<Icomposite>として使用しなければならないでしょうか?

ありがとうございました。

+3

'T 'が構造体の場合はどうなりますか?そうすれば、分散ルールが破られます。コンパイラがアイデンティティを保持する変換となるようにするには、 'class'制約が必要です。参照:[これはC#4の共分散バグですか?](http://stackoverflow.com/questions/2783233/is-this-a-covariance-bug-in-c-sharp-4) – Ani

+0

はい、それは問題は、それは今うまく動作します。ありがとうございます –

+0

の可能な複製[なぜ共分散は一般的な方法で動作しません](http://stackoverflow.com/questions/12743444/why-covariance-does-not-work-with-generic-method) – nawfal

答えて

5

という制約をTに追加することで問題を解決できるはずです。構造体が含まれている場合、共分散は機能しません(IEnumerable<int>IEnumerable<object>に変換できません)。 Tをクラスに制限していないので、IReader<some struct that implements IComposite>を渡すことができます。これは変換できません。

+0

クール、それは今働く、私はすでに共分散が値の種類で動作していないことを知っていましたが、これがこの場合私の問題の原因であることを認識していませんでした。クラスの制約を追加すると、完全に機能します。ありがとうございました !! –

1

残念ながら。ジェネリックは共変ではありません。 IReader<T>およびIReader<IComposite>は、がICompositeに関連しているにもかかわらず、完全に無関係のタイプです。

EDIT:なぜこれが.Net 4と<out T>では機能しないのか分かりません。誰か他の人が答えてくれますか?

private static Func<bool> MakeSynchroFunc<T>(IReader<IComposite> reader) where T : IComposite 

あなたが他のもののためにジェネリックパラメータTが必要な場合がありますので、私はそこに左:これは、あなたが本当に何をしたいものですので、

+1

あなたは本当ですか? IReaderインターフェース定義のout指定子は、インターフェースが共変であることをコンパイラーに通知する必要があります。私は.NET 4を使用しています –

+3

この答えは明確にする必要があります。それは書かれたようにむしろ混乱しています。 –

+0

私は、インターフェイスの共分散についてというキーワードについて知らなかったので、OPのコードがうまくいかない理由がわかりません。私は何かを学んだので質問のために+1、そしてうまくいけば誰かが答えることができます。 – GazTheDestroyer

0

なぜ、関数定義を変更しません。

+0

私は何かのためにパラメータTが必要なので、これは単なる例であり、実際のコードではありません。コンパイラに明示的に指定するのではなく、Tの型を推論させたいと思います。 –