[英]Returning a class that implements a variant interface
背景:
我有三个Silverlight页面,它们实现了我的界面:
interface IPageWithData<in T> where T : Entity
{
void SetData(T obj);
}
public class APage : Page, IPageWithData<AItem> { /* Implementation */ }
public class BPage : Page, IPageWithData<BItem> { /* Implementation */ }
public class CPage : Page, IPageWithData<CItem> { /* Implementation */ }
// AItem, BItem and CItem are (EF) Entities (they are derived from Entity class).
然后,我使用一个自定义管理器,该管理器返回一个页面,该页面与作为参数提供的treeview节点相关:
private static class PageContainerHelper
{
public static IPageWithData<Entity> SetPage(RadTreeViewItem selectedNode)
{
APageRTVI aNode = selectedNode as APageRTVI;
BPageRTVI bNode = selectedNode as BPageRTVI;
CPageRTVI cNode = selectedNode as CPageRTVI;
if (aNode != null)
{
if (APage == null)
APage = new APage();
APage.SetData(aNode.aItem);
return APage; // ERROR HERE
}
/*
... the same for BPageRTVI and CPageRTVI
*/
}
public static APage APage { get; set; }
public static BPage BPage { get; set; }
public static CPage CPage { get; set; }
}
问题:
我似乎错误地理解了co / contravariance。 SetPage()
方法不允许我返回APage
:
无法将类型'MyProject.Views.Pages.APage'隐式转换为'MyProject.Views.Pages.IPageWithData' 。 存在显式转换(您是否缺少演员表?)
APage
实现IPageWithData<T>
(尽管T
具有更多派生类型)。 为什么这需要显式转换? 显式转换在这里是否还能工作?
因此,基本上,我需要两件事。 一种是SetPage
返回页面时,它可以使用实现IPageWithData
的类型的页面,该类型的类型比Entity
派生的更多。 我需要做的另一件事是IPageWithData<T>.SetData
方法能够接收类型比T
派生得多的参数,即Entity
。
这可能吗?
考虑您可以使用IPageWithData<Entity>
做什么。 你可以做:
IPageWithData<Entity> pageWithData = PageContainerHelper.SetPage(...);
BItem item = new BItem();
pageWithData.SetData(item);
现在, 实现是一个APage
您希望它与BItem
一起使用吗? 我怀疑你不想那样。
换句话说,编译器确实在做应做的事情-它可以保护您避免将错误类型的数据发送到无法处理的页面。 我真的不知道如何解决此问题-我怀疑您也希望SetPage
是通用的:
public static IPageWithData<T> SetPage<T>(RadTreeViewItem selectedNode)
where T : Entity
但我不清楚这对您的实施有什么影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.