简体   繁体   English

C#反序列化-可以安全地捕获TargetInvocationException吗?

[英]C# Deserialization - Is it safe to catch TargetInvocationException?

I am using BinaryFormatter to serialize and deserialize some objects. 我正在使用BinaryFormatter序列化和反序列化某些对象。 The structure of those object is as follows: 这些对象的结构如下:

[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
    }
}

I have noticed that when I try to deserialize an object, a TargetInvocation exception is thrown if the "SomeProperty" entry cannot be found (for example, because it was renamed or deleted). 我注意到,当我尝试反序列化对象时,如果找不到“ SomeProperty”条目(例如,因为它被重命名或删除),则会引发TargetInvocation异常。 Since I intend to change the properties of SerializableObject class in future, I was thinking of catching the exception and setting the value of the problematic property to some default value instead of crashing my application, like this: 由于我打算将来更改SerializableObject类的属性,因此我在考虑捕获异常并将有问题的属性的值设置为某个默认值,而不是使应用程序崩溃,例如:

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

As we all know, catching exceptions that you don't know how or cannot handle is a bad practice, so I'm asking whether it's safe to catch it in this place? 众所周知,捕获您不知道如何处理或无法处理的异常是一种不好的做法,所以我问在这个地方捕获它是否安全? Can the same exception be thrown for any other reason (that I don't know and therefore shouldn't handle)? 可以出于任何其他原因(我不知道,因此不应处理)抛出相同的异常吗?

A TargetInvokationException should have an InnerException which will give you more information. TargetInvokationException应该具有一个InnerException ,它将为您提供更多信息。 I'd suggest that you check the inner in the catch block and rethrow if the situation is simply a missing property. 我建议您检查catch块的内部,如果情况仅仅是缺少的属性,则重新抛出。

Since TargetInvocationException is not listed in the set of exceptions you should expect from that method ( see MSDN ) I would say it is wrong to try to handle that. 由于TargetInvocationException 没有列在您应该从该方法获得的异常集中( 请参见MSDN ),我会说尝试处理该错误是错误的。 A better approach is to loop on the names it does have, and pick the ones you expected: 更好的方法是循环使用它确实具有的名称,然后选择所需的名称:

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

Or... use a less fussy serializer ;p 或者...使用不太繁琐的序列化器; p

(btw, the above uses the alternative foreach handling based on a typed enumerator and GetEnumerator() method; it doesn't implement IEnumerable / IEnumerable<T> , but... it doesn't have to; you can use foreach without that) (顺便说一句,以上方法基于类型化的枚举器和GetEnumerator()方法使用了替代的foreach处理;它没有实现IEnumerable / IEnumerable<T> ,但是...并不一定要实现;您可以在没有该方法的情况下使用foreach

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM