简体   繁体   中英

Constrain a list of System.Type to types that inherit from a base type

If I have the code:

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

How would I constrain the types within this list so they have a common parent?

For example:

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

Edit: A little bit more background so maybe people can understand why I need this. I have a class Entity that contains a list of Components . Each component needs to have a list of Component types that acts as a list of dependencies. So at runtime when you try to add a Component to a Entity it will do a quick check to see if that Entity has the required components already attached to it.

Example:

//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; }
//...

After much work I found a solution to my own problem.

//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;
    }
    //...
}

I created a new storage type call RequiresList which checks all System.Type s that are inserted into it to see if they are a subclass of Component . I also made sure that if someone tried to replace the list with an entirely new one it will remove any indexes of the new list that aren't Component s

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM