这是一个基本算法......(伪代码)
function examine(m,examined_so_far=[])
{
result_stuff = something_special
i = get_unique_identifier(m)
if i in examined_so_far
return result_stuff?
examined_so_far.append(i)
attributes = get_attributes(m)
for att in attributes:
result_stuff.add(examine(att, examined_so_far))
do_processing(result_stuff)
return result_stuff
}
用英语:
维护一份你已经看过的东西的清单。这可以通过使用唯一标识符初始化每个 M 实例,或者通过使用实例的内存位置来完成。
说乔和苏是共同的配偶,你打电话给examine(joe)
级别 1:result_stuff 被初始化(我不知道你想要什么),joe 的标识符被添加到列表中
级别 2:检查 sue 并将她的标识符添加到列表中
级别 3:检查 joe 并且他的标识符已经在列表中,因此返回了一些结果内容
级别2:从级别3获取结果,进行一些处理并返回相关结果
级别 1:从级别 2 等获取结果
关于你的第二个问题...
我对 C# 非常生疏,所以我不确定是否有更好的方法来做到这一点,但这是我的第一个想法:为什么不维护一个应该为每个类序列化的属性名称数组?我确定您可以通过名称访问属性。就像在 Python 中一样,以下两个语句是等价的:a = some_object.foo
和a=some_object.__getattribute__('foo')
然后你要做的是让 M 的 serailize-array 包含一个带有信息的条目,'spouse'
然后在序列化它时你将遍历数组。像这样的东西(也是伪代码......):
serial_rep = '{'
for att in self.serialize_array:
serial_representation += att + ':'
serial_representation = serialize(obj.__getattribute__(att))
serial_representation += ','
remove_last_comma(serial_representation)
serial_rep += '}'
那么当调用serialise
一个属性时,你只需要检查它是否有一个 serialise_array 或者它是否是一个基本类型。
例如:
if type(obj) == int:
return obj
if type(obj) == str:
return '"'obj+'"'
if obj.has_attribute(serialise_array):
serial_rep = '{'
for att in self.serialize_array:
etc