我如何使用反射递归来研究具有循环依赖性的类实例?

时间:2012-12-13 14:27:01

标签: c# serialization reflection recursion

考虑您有以下课程:

Class P  
{  
     string m_Name;  
     P m_spouse;  
}

和P的两个实例:
一个。汤姆的配偶是安妮 湾安妮谁的配偶是汤姆

现在我正在尝试通过反射来调查Tom的实例以进行序列化。 当我注意到值类型时,我以Xml格式写出它们的名称和值。 问题是当我到达调查参考类型,如汤姆的配偶,因为然后在Annie调查,但在调查安妮我很快将调查她的配偶汤姆,这是不正常的,因为这将永远不会结束。

问题

  1. 任何想法如何实现最终会停止的递归?
  2. 考虑我需要自己实现序列化功能 您认为我可以在不使用反射的情况下序列化实例以进行调查吗? 有没有办法在没有反射的情况下序列化实例?
  3. 非常感谢

3 个答案:

答案 0 :(得分:2)

这是一个基本算法......(伪代码)

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实例,或使用实例的内存位置来完成。

说乔和sue是共同配偶,你打电话给examine(joe)

1级:result_stuff初始化(我不知道你想要什么),joe的标识符被添加到列表中

级别2:检查sue并将她的标识符添加到列表

级别3:检查joe并且他的标识符已经在列表中,因此返回了一些结果内容

第2级:从第3级获得结果,进行一些处理并返回相关结果

等级1:获得等级2等的结果

关于你的第二个问题......

我对C#非常生疏,所以我不确定是否有更好的方法,但这是我的第一个想法:为什么不维护一个应该按类序列化的属性名称数组?我确定你可以通过名字以某种方式访问​​属性。与Python类似,以下两个语句是等效的:a = some_object.fooa=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

答案 1 :(得分:1)

这里不需要反思。你所拥有的不是循环依赖(在c#中使用它们真的很难)。你所拥有的是一个循环的类结构。

为序列化解决此问题的几种方法,最好的方法是标记Spouse属性[XmlIgnore]并添加另一个SpouseID(或名称或任何用于识别配偶数据的工作)

答案 2 :(得分:0)

你可以主张一些优势......

Class M : P
{
W m_spouse
}
Class W : P
{
M m_spouseof
}