无法在迭代期间获得单独的引用
Unable to get separate references during iteration
我正在尝试遍历实现特定接口的列表成员,称为 ImplementsGraphics
,然后调用方法 GetModels
并将 return 结果添加到列表.
但是,每当我尝试遍历我的对象并执行强制转换操作时,我似乎在我的迭代过程中覆盖了相同的引用。我推断我的问题与我在哪里、何时以及如何实例化我的变量有关,但我无法准确解读预期的行为是什么。
我尝试了以下代码的多种排列:
public List<Model> GetModels()
{
var models = new List<Model>();
foreach (Actor actor in registeredActors.Where(n=>n is ImplementsGraphics))
{
var graphicActor = (ImplementsGraphics)actor;
models.AddRange(graphicActor.GetModels());
}
return models;
}
问题行是 var graphicActor = (ImplementsGraphics)actor;
,但我不知道如何编写它以声明 graphicsActor 不会覆盖存储在模型中的现有实例。
在我的前几轮故障排除之前,我有
public List<Model> GetModels()
{
var models = new List<Model>();
foreach (Actor actor in registeredActors)
{
if((ImplementsGraphics)actor != null)
models.AddRange(((ImplementsGraphics)actor).GetModels());
}
return models;
}
我原以为 actor
在迭代中是安全的,但显然不是。
期望的行为:
Return 一个列表,它是实现 ImplementsGraphics
的 RegisteredActors 中永远的 Actor GetModels()
的所有 return 结果
实际行为:
Return 是一个列表,与实现 ImplementsGraphics 的已注册 Actor 中的每个 Actor 重复相同的 return 值。
编辑:
在 class StaticActor
中,它是 Actor
的子项并实现 ImplementsGraphics
其定义如下:
public List<Model> GetModels()
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = this.Transform.WorldMatrix;
}
}
return new List<Model> { Model };
}
此外,我还尝试了另外两种同样失败的方法。一个 for 循环,遍历所有 RegisteredActors
,并检查它们是否实现了 ImplementsGraphics
,通过它们在 RegisteredActors
中的索引显式调用它们
还有一个 LINQ 查询
var models = RegisteredActors.Where(n=>n is ImplementsGraphics).SelectMany(n=>((ImplementsGraphics)n).GetModels())
编辑 2:
我的 classes 的定义在很大程度上是无关紧要的,如果你想要一个我遇到问题的行为的可重现示例,这里有一个简单得多的示例。
class MyClass
{
MyOtherClass foo = new MyOtherClass();
int bar = 0;
MyOtherClass GetOtherClass()
{
foo.bar = bar;
return foo;
}
}
class MyOtherClass
{
int bar = 0;
}
List<MyClass> MyCollection = new List<MyClass> {new MyClass(bar = 1), new MyClass(bar = 2), new Myclass(bar = 3)};
List<MyOtherClass> MyOtherCollection = new List<MyOtherClass>();
foreach(MyClass member in MyCollection)
{
MyOtherCollection.Add(member.GetOtherClass());
}
如果您执行上述代码,我预计 MyOtherCollection 的条形属性的值将是:1、2、3
然而,实际的结果是:
在第一次迭代期间,值为 1
在第二次迭代期间,值为 2、2
在第三次迭代期间,值为 3, 3, 3
我会出现,因为 none 所提供的代码状态仅暗示您正在尝试重用对单个 Model
实例的引用来绘制多个对象。然后您将同一实例的多个引用添加到 List
.
解决方案可能就像从所有 Model
变量 and/or 容器对象中删除 static
修饰符一样简单。
通常,解决方案是在将对象添加到 List
时创建对象的 Deep Copy,但是,在 XNA
中无法直接执行此操作*1. (不是你想要的)
最好让每个Actor
,或StaticActor
对象直接通过接口中的GetModels()
方法传递自己的Model
(s)实施,而不是使用额外的 class MyOtherClass
.
*1。 XNA
不会为可用的 Model class. It is possible to do this using reflection. In MonoGame
, there is a public Constructor 公开 public 构造函数。
我倾向于根据 "StaticCollidables"、"DrawableStaticCollidables" 和 "DrawableMovingCollidables"...
此技术可能需要更多的前期编码(因此不像 "elegant"),但是,它在内存开销(8 字节 + (4(32 位)或 8(64 bit) 字节取决于 sizeof(Object)
) 每 List) 和 CPU 开销(无转换或 is
)。
如果您试图重复使用同一个模型,但将其放置在不同的位置,请使用 DrawInstancedPrimitives 方法,使用模型的每个 Mesh
中包含的 VertexBuffer
。
请评论以上哪些解决方案适合您(如果有)。如果我遗漏了什么,请告诉我,以便我可以更正答案。
我正在尝试遍历实现特定接口的列表成员,称为 ImplementsGraphics
,然后调用方法 GetModels
并将 return 结果添加到列表.
但是,每当我尝试遍历我的对象并执行强制转换操作时,我似乎在我的迭代过程中覆盖了相同的引用。我推断我的问题与我在哪里、何时以及如何实例化我的变量有关,但我无法准确解读预期的行为是什么。
我尝试了以下代码的多种排列:
public List<Model> GetModels()
{
var models = new List<Model>();
foreach (Actor actor in registeredActors.Where(n=>n is ImplementsGraphics))
{
var graphicActor = (ImplementsGraphics)actor;
models.AddRange(graphicActor.GetModels());
}
return models;
}
问题行是 var graphicActor = (ImplementsGraphics)actor;
,但我不知道如何编写它以声明 graphicsActor 不会覆盖存储在模型中的现有实例。
在我的前几轮故障排除之前,我有
public List<Model> GetModels()
{
var models = new List<Model>();
foreach (Actor actor in registeredActors)
{
if((ImplementsGraphics)actor != null)
models.AddRange(((ImplementsGraphics)actor).GetModels());
}
return models;
}
我原以为 actor
在迭代中是安全的,但显然不是。
期望的行为:
Return 一个列表,它是实现 ImplementsGraphics
GetModels()
的所有 return 结果
实际行为: Return 是一个列表,与实现 ImplementsGraphics 的已注册 Actor 中的每个 Actor 重复相同的 return 值。
编辑:
在 class StaticActor
中,它是 Actor
的子项并实现 ImplementsGraphics
其定义如下:
public List<Model> GetModels()
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = this.Transform.WorldMatrix;
}
}
return new List<Model> { Model };
}
此外,我还尝试了另外两种同样失败的方法。一个 for 循环,遍历所有 RegisteredActors
,并检查它们是否实现了 ImplementsGraphics
,通过它们在 RegisteredActors
还有一个 LINQ 查询
var models = RegisteredActors.Where(n=>n is ImplementsGraphics).SelectMany(n=>((ImplementsGraphics)n).GetModels())
编辑 2:
我的 classes 的定义在很大程度上是无关紧要的,如果你想要一个我遇到问题的行为的可重现示例,这里有一个简单得多的示例。
class MyClass
{
MyOtherClass foo = new MyOtherClass();
int bar = 0;
MyOtherClass GetOtherClass()
{
foo.bar = bar;
return foo;
}
}
class MyOtherClass
{
int bar = 0;
}
List<MyClass> MyCollection = new List<MyClass> {new MyClass(bar = 1), new MyClass(bar = 2), new Myclass(bar = 3)};
List<MyOtherClass> MyOtherCollection = new List<MyOtherClass>();
foreach(MyClass member in MyCollection)
{
MyOtherCollection.Add(member.GetOtherClass());
}
如果您执行上述代码,我预计 MyOtherCollection 的条形属性的值将是:1、2、3
然而,实际的结果是: 在第一次迭代期间,值为 1 在第二次迭代期间,值为 2、2 在第三次迭代期间,值为 3, 3, 3
我会出现,因为 none 所提供的代码状态仅暗示您正在尝试重用对单个 Model
实例的引用来绘制多个对象。然后您将同一实例的多个引用添加到 List
.
解决方案可能就像从所有 Model
变量 and/or 容器对象中删除 static
修饰符一样简单。
通常,解决方案是在将对象添加到 List
时创建对象的 Deep Copy,但是,在 XNA
中无法直接执行此操作*1. (不是你想要的)
最好让每个Actor
,或StaticActor
对象直接通过接口中的GetModels()
方法传递自己的Model
(s)实施,而不是使用额外的 class MyOtherClass
.
*1。 XNA
不会为可用的 Model class. It is possible to do this using reflection. In MonoGame
, there is a public Constructor 公开 public 构造函数。
我倾向于根据 "StaticCollidables"、"DrawableStaticCollidables" 和 "DrawableMovingCollidables"...
此技术可能需要更多的前期编码(因此不像 "elegant"),但是,它在内存开销(8 字节 + (4(32 位)或 8(64 bit) 字节取决于 sizeof(Object)
) 每 List) 和 CPU 开销(无转换或 is
)。
如果您试图重复使用同一个模型,但将其放置在不同的位置,请使用 DrawInstancedPrimitives 方法,使用模型的每个 Mesh
中包含的 VertexBuffer
。
请评论以上哪些解决方案适合您(如果有)。如果我遗漏了什么,请告诉我,以便我可以更正答案。