C#反序列化 - 捕获TargetInvocationException是否安全?

时间:2011-09-29 10:02:18

标签: c# deserialization 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;
    }
}

众所周知,捕捉你不知道怎么处理或不能处理的异常是一种不好的做法,所以我想问一下在这个地方捕捉它是否安全?是否可以因任何其他原因抛出相同的异常(我不知道,因此不应该处理)?

2 个答案:

答案 0 :(得分:4)

TargetInvokationException应该有一个InnerException,可以为您提供更多信息。我建议您检查catch块中的内部并重新抛出,如果情况只是一个缺失的属性。

答案 1 :(得分:2)

由于TargetInvocationException 列在您应该从该方法(see MSDN)开始的异常集中,我会说尝试处理它是错误的。更好的方法是循环使用 所拥有的名称,然后选择您期望的名称:

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

或者...使用一个不那么繁琐的序列化器; p

(顺便说一句,以上内容使用基于类型化枚举器和foreach方法的替代GetEnumerator()处理;它不实现IEnumerable / IEnumerable<T>,但是..它没有;你可以使用foreach而不是那样)