迭代期间无法获得单独的引用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迭代期间无法获得单独的引用相关的知识,希望对你有一定的参考价值。
我试图迭代实现特定接口的列表的成员,称为ImplementsGraphics
,然后调用方法GetModels
并将返回结果添加到列表中。
但是,每当我尝试遍历我的对象并执行转换操作时,我似乎在迭代期间覆盖了相同的引用。我已经推断出我的问题与我在何时,何时以及如何实例化我的变量有关,但我无法完全破译预期的行为。
我尝试了以下代码的大量排列:
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
在迭代过程中是安全的,但显然不是。
期望的行为:返回一个列表,这是GetModels()
在RegisteredActors中实现ImplementsGraphics
的所有返回结果
实际行为:返回一个列表,该列表与已注册的Actor中的每个Actor重复的返回值相同,后者实现ImplementsGraphics。
编辑:
在类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:
我的类的定义在很大程度上是无关紧要的,如果你想要一个我可以解决的行为的可重现的例子,这是一个更简单的例子。
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的bar属性的值为:1,2,3
但是,实际结果是:在第一次迭代期间,值为1在第二次迭代期间,值为2,2在第三次迭代期间,值为3,3,3
我会出现,因为没有提供的代码声明,只是暗示您试图重用对单个Model
实例的引用来绘制多个对象。然后,您将同一实例的多个引用添加到List
。
解决方案可能与从所有static
变量和/或容器对象中删除Model
修饰符一样简单。
通常,解决方案是在将对象添加到Deep Copy时创建对象的List
,但是,在XNA
* 1中不能直接执行此操作。 (不是你想要的)
允许每个Actor
或StaticActor
对象通过接口实现中的Model
方法直接传递自己的GetModels()
,而不是使用额外的类MyOtherClass
会更好。
* 1。 XNA
没有公开Model类的公共构造函数。可以使用反射来做到这一点。在MonoGame
,有一个公共Constructor可用。
我倾向于根据“StaticCollidables”,“DrawableStaticCollidables”和“DrawableMovingCollidables”等属性拆分我的派生类和后续的List
s ...
这种技术可能需要更多的前期编码(因此不像“优雅”),但是,它在内存开销方面更有效(8字节+(4(32位)或8(64位)字节,具体取决于sizeof(Object)
)每List)和CPU开销(没有铸造或is
)。
如果您尝试重用相同的模型,但将其放在不同的位置,请使用DrawInstancedPrimitives方法,使用模型的每个VertexBuffer
中包含的Mesh
s。
请评论上述哪些解决方案适合您(如果有的话)。如果我错过了什么请告诉我,所以我可以纠正答案。
以上是关于迭代期间无法获得单独的引用的主要内容,如果未能解决你的问题,请参考以下文章