我在XNA中遇到了BoundingSpheres的问题。我想将BoundingSphere添加到BoundingSpheres列表中。目前,这是沿着以下方向:
Aircraft(Vector3 pos, float radius, CollisionManager colMan)
{
BoundingSphere sphere = new BoundingSphere(pos, radius);
colMan.AddSphere(sphere)
}
List<BoundingSphere> spheres = new List<BoundingSphere>();
CollisionManager()
{
spheres = new List<BoundingSphere>();
}
AddSphere(BoundingSphere boundingSphere)
{
spheres.Add(boundingSphere);
}
而不是添加引用,它似乎是添加值。我相信这是因为boundingSpheres是结构?我怎么能绕过这个?我尝试了ref关键字,但值仍未在列表中更新。
答案 0 :(得分:2)
直言不讳,你不能,至少不能直接。结构是value types,因此按值传递和存储。即使明智地使用ref
关键字也无法解决问题,因为List<T>.Item
无法返回对值类型的引用。
解决方法是将struct
转换为class
,或将stuct
嵌入class
,或者只处理它是一个事实值类型并对其进行适当处理(即,不要尝试修改本地副本,但在更改时替换列表中的值)。最后一个选项是,imo,最好的。
答案 1 :(得分:0)
值类型按值传递(这意味着您在方法或容器中获取新的新副本)以避免这种情况,您可以将结构更改为类,向结构声明添加接口并将结构框设置为而是存储对接口的引用。
但似乎你正在使用可变结构,这是非常危险的,因为你可能面临非常危险的行为(更多细节见mutable structs considered harmful)。
答案 2 :(得分:0)
您必须将BoundingSphere
的定义从class更改为struct。这是不可能的,因为它是在an assembly outside of your control中定义的。
你无法对结构进行包装,因为每次拆箱时,你都会得到你所持有的结构的副本。
那就是说,你能做到这一点的唯一方法(在我看来,这不是一个好主意)是通过为结构创建一个类包装器,并将属性中的所有调用委托给结构:
public class BoundingSphereWrapper
{
// Set through constructor.
private readonly BoundingSphere _boundingSphere = ...;
// One of the forwarded calls.
public ContainmentType Contains(BoundingBox box)
{
// Forward the call.
return _boundingSphere.Contains(box);
}
// And so on...
}
当然,您无法将这些类实例传递给期望BoundingSphere
的成员,并且您必须尝试检测更改(这几乎不可能,除非实例通过引用传递)你暴露了底层结构。
但是,你真的不想这样做;结构的设计者可能选择它作为结构,原因如下: