如何确保C#中的List始终具有特定元素?

1 c# list elements

我有一个名为GameObject的类,它有一个动态的组件列表.可以随时删除和添加这些组件.组件可能是纹理,声音或转换等.确保此列表始终具有一个Transition组件的最佳方法是什么?每种类型只允许一个组件.

我脑子里有两个可能的解决方案.哪一个是最好的?而且是有没有更好的解决问题的对策?

方法1:

class GameObject {
    private List<Component> components;

    public T GetComponent<T>() where T : Component {
        // search the requested component and return it
        foreach(Component comp in components) {
            if(comp is T) return (T)comp;
        }
        // return null or throw exception when not found
        return null;
    }

    public void RemoveComponent<T>() where T : Component {
        if(typeof(T) != typeof(Transition)) {
            // only remove the componenent if it's not a Transition component
            Component tmp;
            foreach(Component comp in components) {
                if(comp is T) tmp = comp;
                break;
            }
            components.Remove(tmp);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

方法2:

class GameObject {
    // separate variable for the transition component
    private Transition transition;
    private List<Component> components;

    public T GetComponent<T>() where T : Component {
        // if a transition is requestet just return it
        if(typeof(T) == typeof(Transition)) {
            return transition;
        }
        // else: search the requested component in the list
        foreach(Component comp in components) {
            if(comp is T) return (T)comp;
        }
        // return null or throw exception when not found
        return null;
    }

    public void RemoveComponent<T>() where T : Component {
        if(typeof(T) != typeof(Transition)) {
            // only remove the componenent if it's not a Transition component
            Component tmp;
            foreach(Component comp in components) {
                if(comp is T) tmp = comp;
                break;
            }
            components.Remove(tmp);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jaa*_*rus 5

好像您正在尝试创建所谓的实体组件模型.我建议分析一些使用该模型的引擎,例如 Paradox游戏引擎.

实体(游戏对象)和PropertyContainer(组件集合)应该是你特别感兴趣的.

将转换组件保持为单独的字段并将其存储在组件列表中可能是个好主意.由于它可以保证成为每个游戏对象的一部分,因此您可以提供单独的getter属性,以便直接访问此组件以绕过任何查找成本.

由于您似乎每个类型只允许一个组件,因此将组件存储在一个组件中会很有效Dictionary<Type, Component>.与迭代组件和进行类型比较相比,这将提供非常快速的查找.

第二种方法的略微修改版本:

class GameObject
{        
    private readonly Transition transition = new Transition();
    private readonly Dictionary<Type, Component> components = new Dictionary<Type, Component>();        

    public GameObject()
    {
        AddComponent(transition);
    }

    public Transition Transition { get { return transition; } }

    public T GetComponent<T>() where T : Component
    {
        Component component;
        if (components.TryGetValue(typeof (T), out component))
        {
            return (T) component;
        }
        return null;
    }

    public void AddComponent<T>(T component) where T : Component
    {
        Type type = typeof (T);
        if (!components.ContainsKey(type))
        {
            components.Add(type, component);
        }
    }

    public void RemoveComponent<T>() where T : Component
    {                        
        if (typeof(T) != typeof(Transition))
        {
            components.Remove(typeof (T));                
        }
    }
}
Run Code Online (Sandbox Code Playgroud)