不能转换继承的泛型



我正在尝试以下方法,但它给了我一个编译器错误:

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?

我正在使用。net 2.0,因为我正在使用Unity3D。需要我自己铸造吗?我读过协方差和逆变,但我不明白这个

EventHandler<Derived>不是EventHandler<Base>。输入参数是逆变的。所以你的代码也不能在c# 4/。net 4中工作。

你可以通过创建一个包装器来解决这个问题(这个例子只适用于c# 3,但类似的代码可能适用于c# 2):

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

但是使用这种强制转换会失去静态类型的安全性。

要在安全的方向上转换委托,可以使用我的ConvertDelegate<T>方法。

我决定通过使用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;
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新