我目前正在研究一种用于在维度上(在网格中)表示对象的结构,使得可以基于它们彼此的关系来描述和交互它们。目前它的工作原理如下:
所以,我的问题出现在试图让所有网格项相互了解,这就是Matrix的整个目的,这是一个成员通过位置相互了解的集合。我最初的想法是在每个项目中放置一个Top,Bottom,Left和Right邻居,并将其邻居存储在每个成员中。但这不起作用,因为它们是单个实例,不会影响原始对象。我的下一个计划是拥有一个更新机制,当一个更新时,其邻居都更新了它们的定义,当网格更新其邻居时,原始内容将更新。但这不起作用,因为它们互相无限地更新,并且堆栈溢出。
下一个计划是将MatrixItem的引用传递给它的所有邻居,然后每个项目可以简单地相互引用。这不起作用,因为我不知道如何使属性成为另一个对象的引用,获取和设置该属性将动态获取或设置另一个对象,这将在实例化时定义。
我最后的希望是让所有的孩子能够在Matrix中触发一个方法,但我需要让孩子们可以使用它。这是代表们的目的,如果是这样,我在这种情况下如何实现它们?
答案 0 :(得分:0)
有多种方法可以做到这一点。您实际上有一些好的尝试 - 例如,您可以向MatrixItem添加一个属性,其中包含整个Matrix - 它将自动成为引用,因此如果您在任何时候更新列表,则所有其他属性将是已更新 - 但您必须确保使用相同的Matrix列表初始化所有项目:
//your Matrix list is called matrix
for (var i = 0; i < matrix.MaxLength; i++)
matrix.Add (new MatrixItem (foo, otherProperty, matrix));
另一个可能的解决方案将让每个项目知道它的邻居是什么 - 因为邻居也会知道他的邻居,所以你可以递归获得Matrix的所有项目:
var lastMatrixItem = new MatrixItem (foo, otherProperty, null, null);
matrix.add (lastMatrixItem);
for (var i = 1; i < matrix.MaxLength; i++)
{
var newMatrixItem = new MatrixItem (foo, otherProperty, lastMatrixItem, null);
lastMatrixItem.followingItem = newMatrixItem;
matrix.Add (newMatrixItem);
lastMatrixItem = newMatrixItem;
}
但如果您不熟悉参考资料,这有点令人困惑。
实际上,如您所述,甚至可以更新MatrixItem的所有Matrix知识:
我的下一个计划是拥有一个更新机制,当一个更新时,它的neigbours都更新了它们的定义,当网格更新其邻居时,原始内容会更新。
你只需添加警卫。这意味着,您必须检查分配给该属性的值实际上是否与旧值不同,并且只有这样,才更新该属性。然后,如果值是新的,则仅调用其他项的更新程序功能,因此不会导致无限循环。
一个例子:
public class Item
{
private int _id;
public Item Child;
public Item Parent;
public int Id
{
get => _id;
set
{
if (_id == value) //this is the guard
return;
_id = value;
if (Child != null)
Child.Id = _id;
if (Parent != null)
Parent.Id = _id;
}
}
public override string ToString() =>
$"Id: {Id} child: ({Child?.ToString() ?? "-"})";
}
如果防护不存在,则会发生StackOverflow异常,因为构建了无限循环。通过上面的课程,这是可能的:
实际上我在交互式中使用了这个类来演示它。
没有守卫就行不通:
(i被标记为错误的原因是,在StackOverflow异常之后,交互式自身重置)