2012-08-09 4 views
2

있음. Net을 사용하면 필드를 비 직렬화 가능으로 표시 할 수 있으며 직렬화 중에는 필드를 건너 뜁니다..net serialization : 데이터 필드를 선택적으로 무시하는 방법

런타임에서 특정 필드를 직렬화해야하는지 여부를 제어 할 수있는 간단한 방법을 찾고 있습니다.

+1

.NET 직렬화는 여러 가지를 의미 할 수 있습니다. Xml/Binary/Json ... 직렬화의 * 유형 *을 언급하고 있습니까? – James

+0

이진 직렬화 –

+0

@OphirYoktan "이진 직렬화"는 실제로 매우 모호합니다. 실제로 그것이 BinaryFormatter를 의미한다고 가정해야합니까? 이 두 가지는 동의어가 아닙니다. 프레임 워크 (예 :'NetDataContractSerializer')와 외부 라이브러리 (protobuf-net, msgpack 등)에서 모두 .NET 용 바이너리 시리얼 라이저가 여러 개 있습니다. –

답변

3

필드를 비 직렬화 가능으로 표시하는 것에 대한 언급이므로 BinaryFormatter[NonSerialized]을 사용한다고 가정합니다. 그렇다면 조건부 직렬화를 수행하는 유일한 방법은 ISerializable을 구현하고 유사한 생성자를 추가하고 로직을 GetObjectData 구현에 넣는 것입니다. 이것은 지루하고 오류가 발생하기 쉽습니다. TypeDescriptorXmlSerializer에 의해 사용되는 표준 패턴을 사용하여보다 단순한 조건부 직렬화를 갖는 protobuf-net을 보도록 권장하지만 여전히 이진 출력입니다 (실제로는 BinaryFormatter보다 효율적입니다). 특히 : -이 시리얼 라이저와 관련된 아무것도

[ProtoContract] 
public class SomeType { 
    [ProtoMember(1)] 
    public string Name {get;set;} 

    private bool ShouldSerializeName() { 
     // return true to serialize Name, false otherwise 
    } 
} 

ShouldSerialize* 표준 이름 기반 규칙은 없습니다.

여기 ISerializable를 통해 동일합니다 :

[Serializable] 
public class SomeType : ISerializable 
{ 
    public SomeType() { } 
    public string Name { get; set; } 


    void ISerializable.GetObjectData(
      SerializationInfo info, StreamingContext context) 
    { 
     if (/* should serialize Name */) info.AddValue("Name", Name); 
     //... all other fields 
    } 
    protected SomeType(SerializationInfo info, StreamingContext context) 
    { 
     foreach (SerializationEntry entry in info) 
     { 
      switch (entry.Name) 
      { 
       case "Name": Name = (string)entry.Value; break; 
       //... all other fields 
      } 
     } 
    } 
} 

많은 이상을 유지하기 위해; 특히 ISerializable을 사용할 때 모든 구성원에 대해 책임을 져야합니다. 그러나 protobuf-net을 사용하는 경우 사례별로 처리 할 수 ​​있습니다.

사실, 당신은 믹스 앤 매치 할 수도, 즉 당신이 BinaryFormatter를 사용하여 부착하는 경우, 당신은 여전히 ​​protobuf - 그물하는 작업을 오프로드 할 수 있지만, 그것은 형식 변경됩니다 (그래서 호환되지 않습니다 이전 데이터 사용). 예 :

[Serializable, ProtoContract] 
public class SomeType : ISerializable 
{ 
    public SomeType() { } 
    [ProtoMember(1)] 
    public string Name { get; set; } 
    private bool ShouldSerializeName() { /* condition */ } 

    void ISerializable.GetObjectData(
     SerializationInfo info, StreamingContext context) 
    { 
     Serializer.Serialize(info, this); 
    } 
    protected SomeType(SerializationInfo info, StreamingContext context) 
    { 
     Serializer.Merge(info, this); 
    } 
} 
+0

감사합니다. 아주 좋은 대답. –

관련 문제