【问题标题】:Constrain a list of System.Type to types that inherit from a base type将 System.Type 列表约束为从基类型继承的类型
【发布时间】:2018-05-08 03:03:42
【问题描述】:

如果我有代码:

List<Type> Requires = new List<Type>();

我将如何限制此列表中的类型以使它们具有共同的父对象?

例如:

List<Type : Component> Requires = new List<Type>()

编辑:多一点背景,也许人们可以理解我为什么需要这个。我有一个类Entity,其中包含Components 的列表。每个组件都需要有一个 Component 类型列表,作为依赖项列表。因此,在运行时,当您尝试将 Component 添加到 Entity 时,它会快速检查 Entity 是否已附加所需的组件。

例子:

//Entity.cs
//...
_components = new List<Component>();
//...
public T AddComponent<T>() where T : Component, new()
{
    var temp = new T();
    if (_components.Exists((x) => x is T)) return null;
    foreach (var t in temp.Requires)
    {
        if (_components.Exists(x => x.GetType() == t)) return null;
    }
    _components.Add(new T());
    temp.gameObject = this;
    return temp;
}
//...

//Component.cs
//...
protected internal Entity gameObject;
protected internal List<Type> Requires { get; }
//...

【问题讨论】:

  • 为什么不直接说List&lt;Component&gt; Requires = new List&lt;Component&gt;()?该列表中的每个项目都是ComponentComponent 的子类。
  • 我认为他在谈论System.Type类。
  • 我说的是System.Type 类。我将其中的一堆存储在一个列表中,这样我就可以对照一个组件列表检查它们,看看是否有任何重复。

标签: c# list inheritance types


【解决方案1】:

经过大量工作,我找到了解决自己问题的方法。

//Component.cs
public abstract class Component {
    //...
    protected internal Entity gameObject;
    private RequiresList _requires;
    //...
    protected internal RequiresList Requires
    {
        get => _requires;
        private set => _requires = (RequiresList)value.FindAll(x => x.IsSubclassOf(typeof(Component)));
    }
    //...
    public class RequiresList : List<Type>
    {
        public RequiresList() { }
        public RequiresList(IEnumerable<Type> types) : base(types) { }
        public RequiresList(int capacity) : base(capacity) { }

        public new Type this[int index]
        {
            get => base[index];
            set
            {
                if (isComp(value))
                    base[index] = value;
            }
        }

        public new void Add(Type type)
        {
            if (isComp(type))
                base.Add(type);
        }

        private static bool isComp(Type type)
        {
            return type.IsSubclassOf(typeof(Component));
        }
    }
    //...
}

//Entity.cs
public abstract class Entity {
    //...
    _components = new List<Component>();
    //...
    public T AddComponent<T>() where T : Component, new()
    {
        var temp = new T();
        if (_components.Exists((x) => x is T)) return null;
        foreach (var t in temp.Requires)
        {
            if (_components.Exists(x => x.GetType() == t)) return null;
        }
        _components.Add(new T());
        temp.gameObject = this;
        return temp;
    }
    //...
}

我创建了一个新的存储类型调用RequiresList,它检查插入其中的所有System.Types,看它们是否是Component 的子类。我还确保如果有人试图用一个全新的列表替换列表,它将删除新列表中不是 Components 的所有索引

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多