2016-11-01 12 views
-2

ジェネリックスが共分散をサポートしていないことを理解していると思います。最初の例が機能せず、無効なキャスト例外が発生します。すべてがコンパイルされます。ジェネリックの2つの使用の違い(共分散)

しかし、2番目の例はなぜ機能しますか?私はそれが同じものであることだけを見ることができます。

MyClassのは、このようなものです:

public interface IGenericClass<T> { } 
public class MyClass : IGenericClass<SomeType> 
{ 
} 

は動作しない:

public class SendingEmail<T> 
{ 
    IGenericClass<T> abc; 
    public void Send(IGenericClass<T> _abc) 
    { 
     this.abc = _abc; 
    } 
} 

用途:また試してみました

var myClass = new MyClass(); 
SendingEmail<MyClass> sendingEmail = new SendingEmail<MyClass>(); 
sendingEmail.Send(IGenericClass<MyClass>myClass); 
//sendingEmail.Send(myClass); This was wrong 

それは


をコンパイルしたことがないように除去

ワーキング:

class SendingEmail 
{ 
    void Send<T>(MyGenericClass<T> abc) 
    { 

    } 
} 

使用法:

SendingEmail sendingEmail = new SendingEmail(); 
sendingEmail.Send(myclass); 
+1

あなたの実用的な例は、 'SendingEmail sendingEmail = new SendingEmail ();' - 'myclass'でなければなりません。あなたの明示的な 'T - > myclass'ではなく' T - > SomeType'を割り当てます。 – Rob

+1

ジェネリックサポート*安全な共分散* on *インターフェースとデリゲート* *参照型でパラメータ化*。 –

+0

_「すべてがコンパイルされます」_ - 私はどのように見えません。 C#の型安全性は、あなたの正常でない例のような式が 'sendingEmail.Send(myClass)'呼び出しでエラーを伴って正常にコンパイルされないようにするはずです。私はあなたがどのタイプパラメータがどれを混乱させているかについてのコメントに同意しますが、あなたの質問は根本的にはどちらかと言えないようです。これまでのコメントと回答を使用して問題を解決できない場合は、あなたが言うことを行う良い[mcve]が含まれるように問題を修正してください。 –

答えて

2

は、最初の例では、共分散とは何の関係もありません。あなたは簡単に何をT混乱させるのですか? TSomeTypeで、その値はMyClassではありません。

2番目の例では、コンパイラが型を正しく推測させ、それがなぜ機能するかを示しています。

編集

問題が解決しないあなたの質問に編集し、あなたはまだTが何であるかを混乱されていますTMyClassSomeTypeあります。 SendingEmail<T>TSomeTypeabcIGenericType<T>と入力してください。最終的にはIGenericType<SomeType>になります。

コードではSendingEMail<MyClass>と入力したインスタンスを作成しています。これはabcが実際にはIGenericType<MyClass>と間違っていることを意味します。 IGenericType<SomeType>sendingEMail(MyClass)と呼び出すときに実際に行っているものであるIGenericType<IGenericType<SomeClass>>に変換することはできません。

あなたがする必要があるのはvar sendingEmail = new SendingEmail<SomeType>()です。

これはタイプの分散に関連していますが、そうではありません。タイプの差異は、例えばIEnumerable<Animal> animals = Enumerable.Emtpy<Tiger>()を行うことができるもので、IList<T>と同じようにすることはできません。 IEnumerableTで共変であり、IListTで不変である。

C#の配列の共分散が崩れていることに注意してください。以下は合法です。Animal[] animals = new Tiger[3]。あなたが合法的にanimals[0] = new Turtle();をやることができ、幸いにも...あなたがランタイム例外を持っているので、それは壊れています。このシナリオは、IListTで不変である理由とまったく同じです。なぜC#が配列の共分散を壊したのですか?私は知らないが、私はそれが不幸な(おそらく正当化されているが)設計の決定だと考える。

+0

私は私の答えを編集し、あなたの答えが同じであれば疑問に思います。最初の例はまだ共分散とは関係がありませんか? – Carol

+0

@K_Rol編集を参照してください – InBetween

+0

あなたの説明をありがとう。これは私が探していたものです。私は明らかに何かがあったことを知っていましたが、私は何を知っていませんでした。それは何のためのものではありませんか?なぜそれがうまく受け入れられなかったのか分かりません。再度、感謝します – Carol