无法转换继承的泛型?

发布于 2024-12-13 10:08:28 字数 705 浏览 1 评论 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?

我使用的是.net 2.0,因为我使用的是Unity3D。我必须自己投吗?我读过有关协变和逆变的内容,但我无法理解这一点。

I am trying the following method, but it gives me a compiler error:

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

Question: Why can't I convert the handler from K to T?

I am using a .net 2.0, because I am using Unity3D. Do I have to cast it myself? I have read about covariance and contravariance, but I couldn't make sense of this one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

所谓喜欢 2024-12-20 10:08:28

EventHandler 不是 EventHandler。输入参数是逆变的。所以你的代码也无法在 C#4/.net 4 中工作。

您可以通过创建包装器来解决此问题(此示例仅适用于 C#3,但 C#2 也可以使用类似的代码):

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

但是,您会因此失去静态类型安全性。

要以安全的方式转换委托,您可以使用我的 ConvertDelegate< ;T> 方法。

An EventHandler<Derived> is no EventHandler<Base>. Input parameters are contra-variant. So your code wouldn't work in C#4/.net 4 either.

You can work around this by creating a wrapper (This example only works with C#3, but similar code is possible with C#2):

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

But you lose static type safety with this cast.

To convert delegates in the safe direction you can use my ConvertDelegate<T> method.

像你 2024-12-20 10:08:28

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

I've decided to change the dictionary to a more common one by using Delegate and also defining a normal EventFilter class without generics. I hope that the casting will be correct, since I haven't tested this yet. I hope that it will work.

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;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文