【问题标题】:Cannot implicitly convert type to generic type when generic type is parent of type [duplicate]当泛型类型是类型的父类型时,无法将类型隐式转换为泛型类型[重复]
【发布时间】:2020-09-11 19:19:33
【问题描述】:

我尝试通过构建我称为 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 Sandbox\Assets\Scripts\GUI\Sandbox\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 的类。

非常感谢任何帮助!

【问题讨论】:

  • 我相信这是因为GetEntry 需要比BuildControl 需要的派生类型更多。如果将BuildControl 约束为ConsoleConsoleData,错误会消失吗?
  • “当泛型类型是类型的父类型时,无法将类型隐式转换为泛型类型”——你的前提是有缺陷的。您认为所涉及的泛型类型具有父(基)/子(派生)关系,而实际上它们没有。只有 类型参数 可以。但是具有基和子类型参数不会使泛型类型本身成为基和子类型。查看副本。
  • @RufusL 是的,一旦我将 BuildControl 限制为 Console 和 ConsoleData,错误就会消失

标签: c# oop unity3d generics delegates


【解决方案1】:

问题是您试图将BuildMenuEntry&lt;Console, ConsoleData&gt; 放入BuildMenuEntry&lt;T, G&gt; 的数组中。


这是一个有助于理解问题的情况。

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

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

现在我们可以看到Consol.GetEntry 返回一个BuildMenuEntry&lt;Console, ConsoleData&gt;。您不能将BuildMenuEntry&lt;Console, ConsoleData&gt; 放在BuildMenuEntry&lt;Car, CarData&gt; 的数组中,因为Console 不是Car 并且ConsoleData 不是CarData

您放入BuildMenuEntry&lt;T, G&gt; 数组的内容必须是BuildMenuEntry&lt;T, G&gt; 项,其中TG 仍然是泛型,而不是具体的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-04
    • 2013-11-15
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    相关资源
    最近更新 更多