2012-02-07 70 views
0

我试图实现使用.NET IFormatter界面自定义格式。实施IFormatter递归

一对夫妇的搜索小时后,我才发现一个非常基本的样本不幸的是不包括递归。我也尝试使用Reflector来查看BinaryFormatter和SoapFormatter,但它们相当复杂。

我的问题是: 我应该执行递归自己,或者有什么东西我在FormatterServices错过了什么?

下面我的代码:

public void Serialize(Stream serializationStream, object graph) 
{ 
    // Get fields that are to be serialized. 
    MemberInfo[] members = FormatterServices.GetSerializableMembers(graph.GetType(), Context); 

    // Get fields data. 
    object[] data = FormatterServices.GetObjectData(graph, members); 

    // Write class name and all fields & values to file 
    StreamWriter sw = new StreamWriter(serializationStream); 

    string accumulator = string.Empty; 
    for (int i = 0; i < data.Length; ++i) 
    { 
     // Skip this field if it is marked NonSerialized. 
     if (Attribute.IsDefined(members[i], typeof(NonSerializedAttribute))) 
      continue; 

     FieldInfo field = (FieldInfo)members[i]; 
     if (field.FieldType.IsPrimitive) 
     { 
     } 
     else //TODO: What should I do here? 
    } 
    sw.Close(); 
} 

回答

1

如果递归你的意思是对象树遍历然后是,它给你当你实现自己的IFormatter。

简单的检查,如果该属性的值不为空,如果它正在实施IFormatter接口。如果是,那就调用它并使用它返回的值。 如果不是,那么它又取决于你:你可能会抛出一个异常,说IFormatter必须被实现,或者只是退回到某种默认格式化程序(XML或Binary)。

递归本身是棘手的。当,让我们说,对象引用本身,你需要足够的智慧来处理这种情况,而不是与无限循环结束:

public class A { 
    public object SomeProperty { get; set; } 
} 
var a = new A(); 
a.SomeProperty = a; 

有在执行格式化了一些棘手的问题,像什么如果两个属性实际上引用同一个对象?你会序列化/格式化它两次或只是一次,并保持关于这些参考资料的信息? 如果你想只是单向系列化你并不可能需要这一点,但如果你希望能够恢复的对象可能是重要的......