왜 '비 서리 화'속성을 클래스 수준에서 사용할 수 없습니까? 클래스의 직렬화를 방지하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/2467376

문제

이진 직렬화를 사용하여 심하게 클링 된 데이터 객체가 있습니다. 이 데이터 객체는 예를 들어 PriceChanged와 같은 속성 변경된 이벤트를 지원합니다.

핸들러를 PriceChanged에 부착했다고 가정 해 봅시다. 코드가 PriceChanged의 직렬화를 시도하면 핸들러가 직렬화 가능하다는 예외가 발생합니다.

내 대안 :

  • 직렬화 전에 이벤트에서 모든 핸들러를 쉽게 제거 할 수 없습니다.
  • 모든 핸들러의 종속성을 재귀 적으로 표시해야하기 때문에 핸들러를 직렬화 가능한 것으로 표시하고 싶지 않습니다.
  • 나는 pricechanged를 비 설교로 표시하고 싶지 않습니다. 잠재적으로 처리기를 가질 수있는 수십 개의 이벤트가 있습니다. 편집 :이 작업을 수행 할 수없는 또 다른 이유는 데이터 클래스 (및 이벤트)가 생성되어 생성 코드를 직접 제어하지 않기 때문입니다. 이상적으로는 생성 코드는 모든 이벤트가 비 서리화 된 것으로 표시됩니다.
  • 이상적으로는 .NET이 그 시점에서 객체 그래프를 내려 놓고 '잎'으로 만들기를 원합니다. 그렇다면 .NET가 전체 클래스를 비 일리화 된 것으로 표시하지 않도록하는 이유는 무엇입니까?

--

나는 핸들러가 iserializable을 구현하고 직렬화 생성자/ getDataObject 메소드에서 아무것도하지 않게 함으로써이 문제를 해결했다. 그러나 핸들러는 여전히 모든 종속성이 NULL로 설정된 상태에서 직렬화되어 있습니다. 따라서이를 설명해야했습니다.

전체 클래스의 직렬화를 방지하는 더 좋은 방법이 있습니까? 즉, 널 의존성을 설명하지 않아도 되는가?

도움이 되었습니까?

해결책

나는 접근 방식에 동의하지 않는 경향이 있지만 (나는 이벤트를 단순히 비 서리 화로 표시 할 것입니다.

아이디어는 iserializationsurrogate를 구현하는 객체를 만들고 기본적으로 이미하고있는 일을 수행한다는 것입니다. 차이점은 당신이 포함 된 클래스가 아니라 대의원의 직렬화를 사용자 정의하는 것입니다.

같은 것 :

class DelegateSerializationSurrogate : ISerializationSurrogate {
    public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
        // do nothing
    }
    public object SetObjectData(object obj, SerializationInfo info, StreamingContext context) {
        // do nothing
        return null;
    }
}

그런 다음 절차를 사용하여 Formatter에 이것을 등록합니다. 이 MSDN 열에 요약되어 있습니다. 그런 다음 Formatter가 대의원을 만날 때마다 대의원을 직접 직렬화하는 대신 대리를 사용합니다.

다른 팁

... 수십 개의 이벤트가 있습니다 ...

개인적으로, 나는 현장과 같은 이벤트를 위해 다음을 통해 가장 쉽게 수행되는 비 시리얼 마커를 추가합니다.

[field: NonSerialized]
public event SomeEventType SomeEventName;

(수동 지원 대의원을 추가 할 필요가 없습니다)

직렬화 요구 사항은 정확히 무엇입니까? BinaryFormatter 여러면에서 직렬화가 가장 친근한 것입니다. 이벤트에 대한 의미는 약간 추악하며 저장하면 매우 부서지기 쉽습니다 (IMO는 저장에만 운송에만 적합합니다).

하지만; 가장 일반적인 "딥 클론"시나리오를 지원하는 좋은 대안이 많이 있습니다.

  • XmlSerializer (그러나 공개 회원으로 제한)
  • DataContractSerializer / NetDataContractSerializer
  • Protobuf-net (포함 Serializer.DeepClone 이 목적을 위해)

(대부분의 직렬화 지원에서는 추가 속성이 필요할 것이므로 추가하는 것과는 크게 다르지 않습니다. [NonSerialized] 처음에 속성!)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top