C#铸造继承的通用接口 [英] C# casting an inherited Generic interface
问题描述
我有一些麻烦我的头周围投界面我来了。
这是一个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屋!