これが基本的なアルゴリズムです...(疑似コード)
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: スーが検査され、彼女の ID がリストに追加されます
レベル 3: joe が検査され、彼の識別子はすでにリストにあるため、いくつかの結果が返されます
レベル 2: レベル 3 から結果を取得し、何らかの処理を行い、関連する結果を返します
レベル 1: レベル 2 などから結果を取得します
2番目の質問に関しては...
私は C# に非常に慣れていないので、これを行うためのより良い方法があるかどうかはわかりませんが、最初に考えたのは次のとおりです。クラスごとにシリアル化する必要がある属性の名前の配列を維持しないのはなぜですか? 何らかの方法で名前で属性にアクセスできると確信しています。a = some_object.foo
Python と同様に、次の 2 つのステートメントは同等です。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