2011-09-29 55 views
2

我使用BinaryFormatter来序列化和反序列化一些对象。这些对象的结构如下:C#反序列化 - 捕获TargetInvocationException是否安全?

[Serializable()] 
public class SerializableObject : ISerializable 
{ 
    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("SomeProperty", SomeProperty); 
     // similar for other properties 
    } 

    public SerializableObject(SerializationInfo info, StreamingContext context) 
    { 
     this.SomeProperty = (SomePropertyClass)info.GetValue("SomeProperty", typeof(SomePropertyClass)); 
     // similar for other properties 
    } 
} 

我注意到,当我尝试反序列化对象,TargetInvocation异常被抛出,如果“SomeProperty”条目无法找到(例如,因为它被改名或删除)。由于我打算改变SerializableObject类的在未来的性能,我想捕捉异常,并设置有问题的属性值一些默认值,而不是崩溃我的应用程序,像这样的:

public SerializableObject(SerializationInfo info, StreamingContext context) 
{ 
    try 
    { 
     this.SomeProperty = (SomePropertyClass)info.GetValue("SomeProperty", typeof(SomePropertyClass)); 
    } 
    catch (TargetInvocationException) 
    { 
     this.SomeProperty = SomePropertyClass.DefaultValue; 
    } 
} 

我们所有人都知道,捕捉你不知道如何处理或不能处理的异常是一种不好的做法,所以我问是否可以在这个地方捕捉它是否安全?是否可以因为其他原因抛出同样的异常(我不知道,因此不应该处理)?

回答

2

由于TargetInvocationException在设置你应该从法(see MSDN)应该有异常的上市,我会说这是错误的尝试来处理。更好的办法是在其上有名字环路,并挑选你所期望的那些:

foreach(SerializationEntry entry in info) 
    { 
     switch(entry.Name) 
     { 
      case "Foo": //... 
      case "Bar": //... 
     } 
    } 

或...使用不太挑剔串行,P

(顺便说一句,上述用途基于类型化枚举和GetEnumerator()方法替代foreach处理;它没有实现IEnumerable/IEnumerable<T>了。但它不必,你可以用foreach不说)

+0

DataContractSerializer的还是其他什么东西? –

+0

@Ritch我可以*为DataContractSerializer解决问题 - 至少这是基于合同的,这是一个很大的进步。尽管我几乎总是接触protobuf-net,但我有点偏向那里。 –

+0

@Marc - protobuf-net仍处于测试阶段?你现在主张将它用于生产代码吗? - 假装没有偏见;) –

4

A TargetInvokationException应该有一个InnerException这将给你更多的信息。我建议你检查catch块中的内部并重新抛出,如果情况只是一个缺失的属性。