繁体   English   中英

modifiy dictionary value作为out参数和引用

[英]modifiy dictionary value as out parameter and reference

我想创建一个Entity-Component-System示例。 我有像这样的组件

internal struct Position : IComponent
{
    public int X { get; set; }
    public int Y { get; set; }
}

internal struct Movementspeed : IComponent
{
    public float Value { get; set; }
}

哪个实施

internal interface IComponent
{
}

循环遍历组件时,我希望尽可能快地找到它们。 我想过创建一个Dictionary,它将组件类型作为键,组件作为值。

internal class ComponentCollection
{
    public ComponentCollection()
    {
        components = new Dictionary<Type, object>();
    }

    private Dictionary<Type, object> components;

    public void AddComponent<T>(T component) // add a new component
    {
        Type componentType = typeof(T);
        components.Add(componentType, component as IComponent);
    }

    public void RemoveComponent(Type componentType) // remove the component by type
    {
        components.Remove(componentType);
    }

    public bool TryGetComponent<T>(out T component) // get the specified component
    {
        try
        {
            Type componentType = typeof(T);
            component = (T)components[componentType];
            return true;
        }
        catch (Exception)
        {
            component = default(T);
            return false;
        }
    }
}

出现了两个问题。

  1. 如果有人使用float movementspeed movespeed创建一个新的MovementspeedComponent并尝试添加它会怎么样? 有两个浮点数会抛出一个重复的键异常。 我只能添加实现IComponent接口的自定义struct组件来防止重复。

  2. 当我尝试修改组件时,它们不会被引用修改

     private static void Main(string[] args) { ComponentCollection components = new ComponentCollection(); components.AddComponent(new Position()); components.AddComponent(new Movementspeed()); if (components.TryGetComponent(out Position fooPosition)) { fooPosition.X++; Console.WriteLine(fooPosition.X); // prints 1 } if (components.TryGetComponent(out Position barPosition)) { Console.WriteLine(barPosition.X); // prints 0 } Console.ReadLine(); } 

有什么建议么?

如果有人使用float movespeed创建一个新的MovementspeedComponent,该怎么办?

当我们每种类型都有一个对象/集合时类型适用于键,否则Dictionary<Type, object>不合适,key应该是唯一的。

当我尝试修改组件时,它们不会被引用修改

由于所有组件都是struct这段代码:

components.TryGetComponent(out Position fooPosition)

获取字典中包含的struct 的副本 来自C#指南的引用:

根据作业复制结构。 将结构分配给新变量时,将复制所有数据,并且对新副本的任何修改都不会更改原始副本的数据。 在处理诸如Dictionary之类的值类型集合时,这一点很重要。

如果有人使用float movespeed创建一个新的MovementspeedComponent并尝试添加它会怎么样?

我看到2个解决方案。 使用类而不是结构或添加一些Update方法来更新字典中的结构

public void UpdateComponent<T>(T component)
{
    Type componentType = typeof(T);
    components[componentType] = component;
}

然后在完成更新结构后调用此方法:

if (components.TryGetComponent(out Position fooPosition))
{
    fooPosition.X++;
    components.UpdateComponent(fooPosition);
    Console.WriteLine(fooPosition.X); // prints 1
}

如果您将使用类而不是结构,那么您的旧解决方案应该可行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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