c#反序列化——捕获TargetInvocationException是否安全?



我使用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)

相关内容

  • 没有找到相关文章

最新更新