C#铸造继承的通用接口 [英] C# casting an inherited Generic interface

查看:93
本文介绍了C#铸造继承的通用接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些麻烦我的头周围投界面我来了。
这是一个MVP设计C#Windows窗体。我有我对我的表单类实现一个IVIEW类。还有,我得出成各种具体演示了IPresenter。每个主持人将管理的iView根据不同的角色,例如打开对话框输入一个新的数据集与AddPresenter,而不是用这将写入数据到形式的EditPresenter编辑现有的数据。每一种从IPresenter继承。我想使用的代码这样:

I'm having some trouble getting my head around casting an interface I've come up with. It's an MVP design for C# Windows Forms. I have an IView class which I implement on my form classes. There's also an IPresenter which I derive into various specific Presenters. Each Presenter will manage the IView differently depending on the role, for example opening the dialog to enter a new set of data with an AddPresenter as opposed to editing existing data with an EditPresenter which would preload data onto the form. Each of these inherit from IPresenter. I want to use the code as such:

AddPresenter<ConcreteView> pres = new AddPresenter<ConcreteView>();



我基本上有这个工作,但这些主持人和被加载后,他们管理已被捆绑的意见纳入插件运行时,这意味着我需要的插件接口采取了模式参数,其作用Manager类。此模式参数是使用一个工厂方法来创建或者添加或编辑演示,而是因为以显示对话框中调用时以后那我需要通过像这样的IPresenter界面拨打电话:

I basically have this working but these presenters and the views they manage are bundled into plugins which are loaded post runtime which means I need a Manager class which acts as the plugin interface take a "mode" parameter. This mode parameter is use for a factory method to create either the Add or Edit Presenter, but because the call to show the dialog is made later on then I need to make the call via the IPresenter interface like so:

private IPresenter<IView> pres;
public ShowTheForm()
{
    pres.ShowDialog();
}

现在我有问题,当涉及到我的套管的一个具体实例AddPresenter说,到PRES成员。
这里是什么我有一个砍伐简化版本:

Now I'm having issues when it comes to casing my concrete instantiation of an AddPresenter say, to the 'pres' member. Here's a cut down simplified version of what I have:

    interface IView
    {
        void ViewBlah();
    }

    interface IPresenter<V> where V : IView
    {
        void PresBlah();

    }

    class CView : IView
    {
        public void ViewBlah()
        {

        }
    }

    class CPresenter<T> : IPresenter<T> where T : IView
    {
        public void PresBlah()
        {
        }
    }

    private void button3_Click(object sender, EventArgs e)
    {
        CPresenter<CView> cpres = new CPresenter<CView>();
        IPresenter<IView> ipres = (IPresenter<IView>)cpres;

    }

这是错误:

Unable to cast object of type 'CPresenter`1[MvpApp1.MainForm+CView]' to type 'IPresenter`1[MvpApp1.MainForm+IView]'.



无论是演示,从我可以告诉通用类型规范是接口的子类,所以我可以不懂为什么它不会投。

Both the Presenter and the Generic type specification from what I can tell ARE subclasses of the interfaces so I can't understand why it won't cast.

有什么想法?

史蒂夫

推荐答案

问题是泛型类型参数。如果你的接口参数协再投会工作。

The problem is the generic type parameter. If you make the interface parameter covariant then the cast will work.

这是通过添加退出关键字来完成,像这样:

This is accomplished by adding the out keyword, like so:

interface IPresenter<out V> where V : IView
{
    void PresBlah();

}

您可以了解更多关于如何适用于以下MSDN文章:协变和逆变泛型中。本节通用接口有协类型参数专门适用于您的问题。

You can learn more about how this works with the following MSDN article: Covariance and Contravariance in Generics. The section Generic Interfaces with Covariant Type Parameters specifically applies to your question.

更新:请务必检查@phoog和我之间的意见。如果你的实际代码接受 V 作为输入,您将无法使其协变的。在引用的文章和@ phoog的回答解释了这种情况下,进一步的细节。

Update: Make sure you check the comments between @phoog and me. If your actual code accepts a V as an input, you will be unable to make it covariant. The referenced article and @phoog's answer explains this case in further detail.

这篇关于C#铸造继承的通用接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆