我使用BinaryFormatter来序列化和反序列化一些对象。这些对象的结构如下:
[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
}
}
我注意到,当我试图反序列化一个对象时,如果找不到"SomeProperty"条目(例如,因为它被重命名或删除了),就会抛出TargetInvocation异常。由于我打算在将来更改SerializableObject类的属性,我正在考虑捕获异常并将有问题的属性的值设置为一些默认值,而不是崩溃我的应用程序,像这样:
public SerializableObject(SerializationInfo info, StreamingContext context)
{
try
{
this.SomeProperty = (SomePropertyClass)info.GetValue("SomeProperty", typeof(SomePropertyClass));
}
catch (TargetInvocationException)
{
this.SomeProperty = SomePropertyClass.DefaultValue;
}
}
我们都知道,捕获不知道如何处理或无法处理的异常是一种不好的做法,所以我想问的是,在这里捕获它是否安全?同样的异常是否会因为任何其他原因(我不知道,因此不应该处理)而被抛出?
一个TargetInvokationException
应该有一个InnerException
,它会给你更多的信息。我建议您检查catch块的内部,如果情况只是缺少属性,则重新抛出。
由于TargetInvocationException
是不是列在一组异常中,你应该期望从该方法(见MSDN),我会说这是错误的尝试处理。更好的方法是循环它所具有的名称,并选择您期望的名称:
foreach(SerializationEntry entry in info)
{
switch(entry.Name)
{
case "Foo": //...
case "Bar": //...
}
}
还是……使用不那么繁琐的序列化器;p
(顺便说一句,上面使用了基于类型化枚举器和GetEnumerator()
方法的foreach
处理;它没有实现IEnumerable
/IEnumerable<T>
,但是…它不需要;你可以不用foreach
)