[英]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;
}
}
}
出现了两个问题。
如果有人使用float movementspeed
movespeed创建一个新的MovementspeedComponent并尝试添加它会怎么样? 有两个浮点数会抛出一个重复的键异常。 我只能添加实现IComponent
接口的自定义struct组件来防止重复。
当我尝试修改组件时,它们不会被引用修改
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.