返回实现变体接口的类

发布于 2024-11-26 13:29:49 字数 1904 浏览 0 评论 0原文

背景:

我有三个 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).

然后我使用自定义管理器返回一个与作为参数给出的树视图节点相关的页面:

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

问题:

我似乎以错误的方式理解协变/逆变。 SetPage() 方法不允许我返回 APage

无法将类型'MyProject.Views.Pages.APage'隐式转换为'MyProject.Views.Pages.IPageWithData'。存在显式转换(您是否缺少强制转换?)

APage 实现 IPageWithData(尽管 T 是更派生的类型)。为什么这需要显式转换?显式转换在这里还能工作吗?

基本上,我需要两件事。一是当 SetPage 返回页面时,它可以使用实现比 Entity 更派生的类型的 IPageWithData 的页面。我需要的另一件事是 IPageWithData.SetData 方法能够接收比 T 更派生的类型的参数,即 <代码>实体。

这可能吗?

Background:

I have three Silverlight Pages, that implement my interface:

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).

Then I use a custom manager that returns a page that relates to the treeview node given as a parameter:

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

Problem:

I seem to be understanding co/contravariance the wrong way.
The SetPage() method doesn't allow me to return APage:

Cannot implicitly convert type 'MyProject.Views.Pages.APage' to 'MyProject.Views.Pages.IPageWithData'. An explicit conversion exists (are you missing a cast?)

APage implements IPageWithData<T> (albeit T is of a more derived type). Why does this require a explicit conversion? And would an explicit conversion even work here?

So basically, there are two things I need. One is that when SetPage is returning a page, it can use a page that implements IPageWithData of a type that is more derived than Entity. And the other thing I need is for the IPageWithData<T>.SetData method to be able to receive arguments that are of a type more derived than a T, that is Entity.

Is this possible?

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

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

发布评论

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

评论(1

┈┾☆殇 2024-12-03 13:29:49

考虑一下您可以使用 IPageWithData 做什么。您可以这样做:

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

但我不清楚这对你有什么影响执行。

Consider what you can do with IPageWithData<Entity>. You can do:

IPageWithData<Entity> pageWithData = PageContainerHelper.SetPage(...);
BItem item = new BItem();
pageWithData.SetData(item);

Now the implementation is an APage - what would you want it to be able to do with a BItem? I suspect you don't want that.

In other words, the compiler is doing exactly what it should - it's protecting you from sending the wrong kind of data to a page which can't handle it. Quite how you want to fix this, I don't really know - I suspect you want SetPage to be generic too:

public static IPageWithData<T> SetPage<T>(RadTreeViewItem selectedNode)
    where T : Entity

but it's not clear to me what that does to your implementation.

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