当泛型为类型的父级时,无法将类型隐式转换为泛型

问题描述

我试图通过构建称为Worldobjects的对象来构建由Unity制作的游戏。 Worldobjects是通过由管理器(WorldobjectDataManager)控制的数据类(WorldobjectData)生成的。需要修复的部分是产生Worldobjects的过程。长话短说,我必须将两个通用参数传递给Worldobject构建器:第一个是Worldobject的类型,第二个是数据类的 type (这样脚本可以获取正确的WorldobjectDataManager)。

错误CS0029无法隐式转换类型 'SandBox.GUI.SandBox.BuildButton.BuildMenuEntry ' 到'SandBox.GUI.SandBox.BuildButton.BuildMenuEntry 'Assembly-CSharp C:\ Unity Projects \ 80s 沙箱\资产\脚本\ GUI \沙箱\ BuildButtons \ BuildButtonsChildren \ BuildControl.cs 16有效

这是我尝试编译Console.GetEntry()时遇到的错误

using SandBox.Selectables.Entities.JobInteractables.Worldobjects;
using SandBox.Selectables.Entities.JobInteractables.Worldobjects.Consoles;

namespace SandBox.GUI.SandBox.BuildButton // Used to spawn Worldobjects via a button
{
    /// <summary>
    /// BuildButton used for control buildings (e.g.: consoles)
    /// </summary>
    public class BuildControl<T,G> : CreateBuildButtonNew<T,G> where T : Worldobject where G : WorldobjectData
    {
        protected override BuildMenuEntry<T,G>[] GetBuildMenuEntries()
        {
            return new BuildMenuEntry<T,G>[]
            {
                Console.GetEntry()
            };
        }
    }
} 

Console.GetEntry的编码如下:

public static BuildMenuEntry<Console,ConsoleData> GetEntry()
        {
            return new BuildMenuEntry<Console,ConsoleData> // Console and ConsoleData inherit from Worldobject and WorldobjectData respectively
            {
                entryName = UIStringID,// string
                entrysMaterials = new WorldobjectMaterial[] { WorldobjectMaterial.Steel },// WorldobjectMaterial is an enum
                associatedFunction = InitializeByStatic<Console,ConsoleData> // the spawning function
            };
        }

最后,BuildMenuEntry:

using SandBox.Selectables.Entities.JobInteractables.Worldobjects;

namespace SandBox.GUI.SandBox.BuildButton
{
    public struct BuildMenuEntry<T,G> where T : Worldobject where G : WorldobjectData
    {
        public string entryName;
        public WorldobjectMaterial[] entrysMaterials;
        public SpawnWorldobject<T,G> associatedFunction;
    }
}

我不知道这里出了什么问题,因为T和G分别被约束为Worldobject和WorldobjectData,而Console.GetEntry返回了一个其通用类型继承自Worldobject和WorldobjectData的类。

非常感谢您的帮助!

解决方法

问题是您试图将BuildMenuEntry<Console,ConsoleData>放入BuildMenuEntry<T,G>的数组中。


在这种情况下,这将有助于理解问题。

您的课程BuildControl<T,G>是通用的。假设我们将其用作BuildControl<Car,CarData>。在这种情况下,您的方法可以这样读取:

protected override BuildMenuEntry<Car,CarData>[] GetBuildMenuEntries()
{
    return new BuildMenuEntry<Car,CarData>[]
    {
        Console.GetEntry()
    };
}

现在,我们可以看到Consol.GetEntry返回了BuildMenuEntry<Console,ConsoleData>。您不能将BuildMenuEntry<Console,ConsoleData>放在BuildMenuEntry<Car,CarData>的数组中,因为Console不是Car,而ConsoleData不是CarData。 / p>

您在BuildMenuEntry<T,G>数组中放入的内容必须是BuildMenuEntry<T,G>个项目,其中TG仍然是泛型,而不是具体的。