2011-11-02 18 views
0

私は、次のメソッドをしようとしていますが、それは私のコンパイラエラーを与える:継承された汎用は変換できませんか?

public class MyManager<T> : where T:MyEventArgs 
{ 
    private Dictionary<EventHandler<T>, EventFilter<T>> m_cSubscriptions; 

    public void Subscribe<K>(EventHandler<K> _cHandler, EventFilter<K> _cFilter) 
    where K:T 
    { 
     try 
     { 
      // cannot convert EventHandler<K> to EventHandler<T> 
      m_cSubscriptions.Add(_cHandler, _cFilter); 
     } 
     catch (ArgumentException) 
     { 
      m_cSubscriptions[_cHandler] = _cFilter; 
     } 
    } 
} 

は質問:なぜ私はKからTまでハンドラを変換することはできませんか?

Unity3Dを使用しているため、私は.net 2.0を使用しています。それを自分でキャストしなければならないのですか?私は共分散と反共分散について読みましたが、私はこのことを理解できませんでした。

+0

.Net 2がサポートしていない共分散を使用しようとしています。 – SLaks

答えて

0

私はDelegateを使用しても、ジェネリック医薬品なしで通常のEventFilterクラスを定義することで、より一般的なものに辞書を変更することを決めました。私はまだ試していないので、キャスティングが正しいことを願っています。それがうまくいくことを願っています。

public class MyManager<T> : where T:MyEventArgs 
{ 
    private Dictionary<Delegate, EventFilter> m_cSubscriptions; 

    public void Subscribe<K>(EventHandler<K> _cHandler, EventFilter<K> _cFilter) 
    where K:T 
    { 
     try 
     { 
      // cannot convert EventHandler<K> to EventHandler<T> 
      m_cSubscriptions.Add(_cHandler, _cFilter); 
     } 
     catch (ArgumentException) 
     { 
      m_cSubscriptions[_cHandler] = _cFilter; 
     } 
    } 
} 
0

EventHandler<Derived>は、EventHandler<Base>ではありません。入力パラメータは反対の形をしています。したがって、あなたのコードはC#4/.net 4でも動作しません。

あなたがラッパーを作成することによってこの問題を回避することができますが(この例では、C#3で動作しますが、同様のコードは、C#2で可能です):

(s,e) => handler(s, (K)e) 

しかし、あなたは、このキャストで静的な型の安全性を失います。

代理人を安全な方向に変換するには、ConvertDelegate<T>メソッドを使用できます。

+0

しかし、私がすでに「K:T」を確認していれば、私はそれを安全にキャストできますか? – Marnix

+0

@Marnix安全にキャストするには 'T:K'が' K:T'ではないことを確認する必要があります。私が言ったように、 'in'パラメータは、contra-variantです。 – CodesInChaos

+0

本当です。 'EventFilter 'を 'EventFilter 'に変換することはできないので、ConvertDelegateメソッドは完全には機能しません。そして 'EventFilter'は単純なクラスです。これらの汎用オブジェクトをベースリストに入れるには、より良い方法は何ですか?私はインターフェイスで何かを見つけましたか?:http://www.fotia.co.uk/fotia/DN.01.CoVariantGenericList.aspx – Marnix

関連する問題