2011-09-29 9 views
2

일부 개체를 직렬화 및 비 직렬화하기 위해 BinaryFormatter를 사용하고 있습니다. 다음과 같이 그 객체의 구조는 다음과 같습니다은 "SomeProperty"항목을 찾을 수없는 경우C# deserialization - TargetInvocationException을 catch하는 것이 안전합니까?

[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 예외가 발생합니다 것으로 나타났습니다 (예를 들어, 이름이 변경 되었기 때문에 또는 삭제됨). 나는 미래에 SerializableObject 클래스의 속성을 변경하려는 때문에,이 같은 예외를 잡기 설정 문제가있는 속성 값을 일부 기본값으로 대신 내 응용 프로그램 충돌의 생각 : 우리로

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

모두 알고 있습니다. 어떻게 처리 할 수 ​​있는지 또는 처리 할 수 ​​없는지를 모르는 예외를 잡는 것은 나쁜 습관입니다. 그래서이 장소에서 그것을 잡는 것이 안전한지 묻습니다. 다른 예외적 인 이유 (내가 모르기 때문에 처리해서는 안 됨)에서 같은 예외를 던질 수 있습니까?

답변

2

는 내가 그 처리하려고 잘못 말할 것입니다 당신이 그 방법 (see MSDN)에서 기대해야 예외의 설정에 나와 하지입니다. 더 나은 방법은이 있나요 이름에 루프, 그리고 당신이 예상하는 사람 선택 :

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

또는 ... 덜 까다로운 시리얼 라이저 사용; P

(BTW, 위의 사용을 입력 된 열거 및 GetEnumerator() 방법에 따라 대체 foreach 처리, 그것은 IEnumerable/IEnumerable<T> 구현하지 않습니다,하지만 ... 그것을하지 않습니다 당신이없는 foreach)

+0

DataContractSerializer 또는 뭔가를 사용할 수 있습니까? –

+0

@Ritch'DataContractSerializer'에 대해 * 정착 * 할 수 있습니다. - 적어도 계약을 기반으로합니다. 이는 큰 발전입니다. 나는 거의 항상 protobuf-net에 도달했다. 그러나 나는 다소 편향되어있다. –

+0

@Marc - protobuf-net은 아직 베타 버전입니까? 현재 프로덕션 코드에서 그 사용을 주장 하시겠습니까? - 편견을 가장하는 척하십시오;) –

4

TargetInvokationException에는 InnerException이 있어야 자세한 정보를 얻을 수 있습니다. 상황이 단순히 누락 된 속성 일 경우 catch 블록에서 내부를 확인하고 다시 시작하는 것이 좋습니다. TargetInvocationException 이후