首页 > 解决方案 > 如何制作泛型类的动态列表列表,其中 T: struct?

问题描述

我在列出类型参数是动态和结构的泛型类型时遇到问题。我认为最好在这里举个例子。

public class Container
{
    public List<B<dynamic>> someList = new List<B<dynamic>>();

    public void AddToList(Type type)
    {
        var genericType = typeof(B<>);
        var generic = genericType.MakeGenericType(type);

        someList.Add(Activator.CreateInstance(generic) as B<dynamic>);
    }
}

public class B<T> where T : struct
{

}

我怎么能得到这样的东西而没有得到

错误 CS0453:类型“动态”必须是不可为空的值类型才能将其用作泛型类型或方法“B”中的参数“T”

场景正在为我的游戏制作物品系统。游戏本身是实体组件系统架构,因此游戏中的一切都是带有一些组件(结构)的实体。我正在制作 ScriptableObject 的 Item 类(一种可以保存到 xml 文件的模板)。我希望 Item 的每个实例都有这个项目特定的组件,其中包含项目特定的值。但问题是我不希望这个项目的每个实例都相同,但我希望这个项目在指定范围内有一些随机值。我这样做是为了让 Item 具有 ComponentSetup<>(在我的示例中为 B<>) 的列表,该列表采用 Components(structs) 并使用反射为 Component 具有的每个属性创建最小/最大值。在项目中,我需要访问 ComponentSetup 的一些功能,所以我需要列出 ComponentSetup<> 但可以

标签: c#genericsdynamicstruct

解决方案


我知道这是线程坏死,但为了 OP 和遇到同样情况的任何人的利益,我试图实现与 OP 完全相同的事情。以下是我在游戏中解决和实施此问题的方法:

Unity 的文件是MonoScripts,因此不是真正有效的类型。当我们将脚本或游戏对象拖到检查器时,Unity 使用反射从脚本中提取有用的类型和方法。

MonoScript提供了GetClass()返回classstruct定义在其中的错误,但是如果结构是在命名空间中定义的,则会报告有关它返回错误的错误 - 在我的情况下,它返回 null:

https://issuetracker.unity3d.com/issues/monoscript-dot-getclass-returns-null-when-the-script-contains-a-struct-inside-a-namespace-or-an-interface-inside-a-命名空间

因此,对于任何尝试实现类似功能的人,如果您希望将通用对象作为自定义脚本(组件结构)传递或填充组件列表,请将条目强制转换为MonoScript并调用GetClass()避免在命名空间中定义类型。这是一些用于澄清的伪实现:

// Assuming retrieving list of components from a List<UnityEngine.Object>
foreach (entry in componentList) {
    Type ComponentType = (entry as MonoScript).GetClass();
    var component = Activator.CreateInstance(ComponentType);
    entity.AddComponent(component);
}

推荐阅读