unity3d 页面管理器类中定义的getter方法的动态返回类型?

tct7dpnv  于 2023-11-22  发布在  其他
关注(0)|答案(2)|浏览(190)

我只写了不到两年的代码,在C#上更是如此,所以请对我宽容些:)
所以基本上,我正在为一个移动的应用程序开发的Unity项目工作(不要问我们为什么选择Unity)
该应用程序由多个页面组成,每个页面都有一个附加到它的~ PageBehavior脚本,该脚本派生自PageIDSystem : MonoBehavior类。
PageIDSystem的简化版本如下:

public abstract class PageIDSystem : MonoBehaviour
{
    public enum eDisplayPage
    {
        Page1,
        Page2,
        //and so on
    }

    public eDisplayPage PageID;
}

字符串
任何继承了这个类的页面都将被分配其继承的成员PageID(通过Unity检查器,或者在awake()调用时设置,等等)
为了管理和集中页面之间的移动,我实现了一个单例PageManager类。manager类中有常用的GetPage(~~), GetCurrentPage(~~), SetPage(~~), etc..方法。
这里是我的问题。我想让GetPage(eDisplayPage pageType)方法输出相应的页面,其类型是特定的PageIDSystem派生类。
GetPage()的理想行为和用法如下所示:

PageManager.Instance.GetPage(eDisplayPage.Page1).SomeMethodDefinedInPage1();
PageManager.Instance.GetPage(eDisplayPage.Page2).SomeOtherIdkInitializeParam("init");


在我问如何实现这一点之前,我已经尝试了两种不同的方法来解决这个问题。
首先是使用dynamic作为GetPage()的输出类型,并使用Convert.ChangeType()方法将page(其类型还为PageIDSystem)转换为特定于page的类型。
这个方法失败了,因为(根据我的理解,)dynamic关键字在运行时推导出Unity不允许的返回类型。
其次是使用泛型来定义它,这很有效。下面是我基本上是如何实现它的:

public T GetPage<T>(eDisplayPage ID) where T : PageIDSystem
{
    // find page corresponding to the input ID
    return page as T;
}


这个方法可以工作,但我对此不满意,因为我觉得我在重复使用这个方法。要使用这个方法,我必须将特定于页面的类和pageID作为输入提供给方法,像这样:

PageManager.Instance.GetPage<Page1Behavior>(eDisplayPage.Page1).SomePage1Method();
//                                ^                        ^ these two info is redundant no?


是的,这些是我到目前为止尝试过的方法,但我想知道是否有更优雅的方法来实现这个GetPage()函数,以便它像我上面描述的那样工作。
提前感谢!!

qyuhtwio

qyuhtwio1#

如果你不能在你的Map中有几个相同类型但ID不同的对象,你可以完全删除你的ID,并使用type作为键。它将删除你的“重复”。
然而,这个解决方案本身看起来很奇怪。因为它看起来像是将应用程序的所有部分相互连接起来的方式。而且很难维护这样的软件。我的意思是,

PageManager.Instance.GetPage<Page1Behavior>(eDisplayPage.Page1).SomePage1Method();

字符串

ifmq2ha2

ifmq2ha22#

我认为你应该通过继承你的PageIDSystem或者调用一些从“RefreshPage”接口继承的组件来直接实现不同的页面行为。
就像这样:

public abstract class PageIDSystem : MonoBehaviour
{
    public enum eDisplayPage
    {
        Page1,
        Page2,
        //and so on
    }

    public eDisplayPage PageID;

    public abstract void Refresh();
}

public class Page1Behaviour : PageIDSystem 
{
    public override void Refresh()
    {
        // implement your method here
    }
}

字符串
然后你可以简单地将这些不同的页面行为附加到你的不同的页面对象上,并简单地调用:
第一个月
通常你不需要让页面管理器知道不同页面之间的不同行为,它只需要识别Refresh方法就可以了。

相关问题