2011-11-10 4 views
1

나는 Project 클래스를 직렬화하여 프로젝트 파일을 저장하는 프로그램을 만들고있다. 아직 작업 중이므로 Project 클래스의 일부 클래스는 수시로 변경됩니다 (예 : 클래스에 새 속성이 있음). "단순한"직렬화가 불가능합니다.변경된 클래스의 비 직렬화

해결 방법이 있습니까? 내 말은, 맞춤 serializer 없이는? (아마 지금 내 수준보다 높은 것입니다)

다만 BinaryFormatter를 사용하고 있습니다.


나는 아래에서 썼다. 나는 나를 위해 일할 해결책을 찾았다. 그러나 정답으로 내 대답을 확인할 수 없습니다.) 모든 답변과 의견을 보내 주셔서 감사합니다. 다른 프로젝트에서 사용할 수있는 deserialization 문제를 해결하는 다른 방법을 찾았습니다.

+2

변경 사항이 자주 발생하지 않으면 버전을 구현하는 것이 좋습니다. 이 기사가 도움이 될 수있는 가장 좋은 방법인지는 모르겠습니다. 오래된 문서이기 때문에 볼 수있는 곳 일 수도 있습니다. http://msdn.microsoft.com/en-us/library/ms229752 (v = vs80) .aspx - 또한 형식을 변경하지 않으면 버전 관리가 도움이 될 것입니다. –

+1

아마도 유물을 재현 할 길을 만드는 것이 좋을 것입니다. 일부는 대본을 쓸 수 없다면 건물을 짓지 말아야한다고 말할 수도 있습니다. 이 로직이 종종 DB에 적용되는 것을 보았습니다.이 경우에도 데이터를 다시 얻을 수있는 방법이 있습니다. –

+0

@Merlyn Morgan-Graham 나는 그것을 테스트하기 위해 건축 중이다. 테스트 속도를 높이는 데 도움이되는 저장된 프로젝트가 비 직렬화되지 않았고 릴리스 빌드 이후에이 문제를 미래의 문제로 생각하기 시작했습니다. –

답변

0

, 날 위해 일하는 것이다.

Version Tolerant Serialization에 설명 된 버전 지정은 정말 좋은 생각이지만 [Serializable] 속성 만 사용하는 경우에 유용합니다.

ISerializable 인터페이스를 사용하고 있음을 (내 실수) 쓰는 것을 잊어 버렸습니다. 직렬화 정보 생성자 SerializationInfo 객체에 MemberCount 속성이 있다는 것을 발견했습니다. 때때로 새로운 속성/멤버 만 추가하면 문제가 해결됩니다. 이 정보를 사용하여 이전 파일에서 직렬화 할 수없는 새 멤버/속성을 기본값으로 설정하거나 일부 프롬프트 양식을 사용할 수 있습니다.

다른 방법으로는 비 직렬화에서 어셈블리 버전과 같은 것을 첫 번째 비 직렬화 멤버로 사용합니다. 이는보다 복잡한 클래스 변경으로 직렬화 복원 문제를 해결할 수 있습니다.

어느 쪽이든, 나는 Merylin에 동의합니다. "뭔가를 대본으로 작성할 수 없다면, 그것을 구축해서는 안됩니다." ;)

1

내 경험에 비추어 볼 때, 정말 나쁜 생각을 바꿀 데이터 유형의 직렬화/역 직렬화에 BinaryFormatter을 사용했다. 데이터 유형이 변경되면 내가 알고있는 것에서 BinaryFormatter이 실패합니다.

사용하고있는 데이터 유형에서이 문제를 극복하기 위해 필자는 필자 만의 시리얼 라이저를 작성해야만했다. BinaryReaderBinaryWriter 클래스를 사용하여 유형에 상관없이 데이터를 읽고 쓸 수 있습니다. 이렇게하면 기본 값을 추가하거나 속성을 모두 건너 뛰거나 손상된 데이터를 나타내는 Exception 양식을 보내서 누락 된 데이터를 처리하고 예상되는 데이터를 제어 할 수 있습니다. 자세한 내용은 위의 MSDN 문서 링크를 참조하십시오.

2

나는 당신의 문제를 올바르게 이해하기를 바랍니다. 파일에 직렬화 된 클래스가 있습니다. 그런 다음 메모리의 클래스를 변경합니다 (예 : 다른 속성 추가). 파일에서이 클래스를 deserialize하고 싶지 않습니다. 에만 새 속성을 추가하면 아무런 문제가 없습니다. 그들은 디시리얼라이저에 의해 무시 될 것입니다. 그는 클래스의 새 인스턴스를 만듭니다 (이유는 serializable 클래스 에 기본 생성자이 있어야하는 이유입니다). 그러면 스트림에서 발견 한 속성을 채워서 데이터를 역 직렬화합니다. 속성 유형을 변경하거나 속성을 제거하면 해당 항목을 비 직렬화 할 수 없습니다.

"속성 제거"에 대한 한 가지 해결 방법은 의도적으로 제거하려는 속성을 유지하고 더 이상 무시하는 것일 수 있습니다. 자신의 유형을 변경 한 속성에 대한 workaraound 어쩌면이 예컨대 : 내가 해결책을 발견했습니다 Merlyn 모건 - 그레이엄의 댓글에서 도움을

[Serializable] 
public class MyClass 
{ 
    int? newProperty; 
    [XmlElement("Property")] 
    public string OldProperty 
    { 
     get { return string.Empty; } 
     set 
     { 
      if (!newProperty.HasValue) 
      { 
        int temp; 
        if (int.TryParse(value, out temp)) 
        { 
         newProperty.Value = temp; 
        } 
      } 
     } 
    } 

    public int NewProperty 
    { 
     get { return newPropery.HasValue ? newProperty.Value : 0; } 
     set { newProperty.Value = value; 
    } 
}