2009-07-02 6 views
84

저는 완전히 불가능하다고 생각했습니다. 객체를 비 직렬화 할 때 DataContractSerializer가 생성자를 호출하지 않습니다.! DataContractSerializer가 내 생성자를 호출하지 않습니다?

는 예를 들어,이 클래스를 가지고 :

[DataContract] 
public class Book 
{ 
    public Book() 
    { // breakpoint here 
    } 

    [DataMember(Order = 0)] 
    public string Title { get; set; } 
    [DataMember(Order = 1)] 
    public string Author { get; set; } 
    [DataMember(Order = 2)] 
    public string Summary { get; set; } 
} 

내가 그 클래스의 객체를 직렬화 할 때, 중단 점을 공격하지 않습니다. 이 객체를위한 유일한 생성자이기 때문에 나는 그것이 어떻게 가능한지 전혀 모른다!

내가 아마 추가 생성자 때문에 DataContract 속성의 컴파일러에 의해 생성 된 것으로 가정,하지만 난

그래서 ... 반사를 통해 찾을 수 없습니다, 내가 알고 싶은 것입니다 : 생성자를 호출하지 않고 어떻게 클래스의 인스턴스를 만들 수 있습니까 ??

참고 : 역 직렬화가 시작될 때 OnDeserializing 특성을 사용하여 개체를 초기화 할 수 있다는 것을 알고 있습니다. 이것은 제 질문의 주제가 아닙니다.

+3

또는 "OnDeserialized", 개체가 deserializing을 마쳤을 때 누락 된 필드를 채 웁니다. –

+1

이 질문은 내 마음도 넘어 섰다 : http://stackoverflow.com/questions/178645/how-does-wcf-deserialization-instantiate-objects-without-calling-a-constructor –

답변

118

DataContractSerializer (같은 BinaryFormatter)는 어떤 생성자를 사용하지 않습니다. 객체를 빈 메모리로 만듭니다. 예를 들어

:

Type type = typeof(Customer); 
    object obj = System.Runtime.Serialization. 
     FormatterServices.GetUninitializedObject(type); 

가정은 역 직렬화 프로세스 (또는 콜백 필요한 경우) 완전히 초기화 것입니다.

+82

이것은 CHEATING !! – Cheeso

+0

역 직렬화 할 때 생성자를 전혀 호출하지 말아야합니다. 호출 된 경우 1) 생성자에서 만든 리소스는 어떻습니까? 그들은 누설 될 것이다! 2) 개체를 생성자에서 한 번, deserialized 값으로 한 번 두 번 초기화합니다. – Dudu

+1

@Dodu a : 누수가 발생하지 않습니다. b : (ctor를 호출하는) 많은 serializer가 작동하는 방식입니다. 어느 쪽이든 일반적으로 동작이 이해되는대로 로그가 좋으며 디자이너는 –

3

일부 시나리오는이 동작 없이는 가능하지 않습니다. 다음을 생각하십시오.

1) 새 인스턴스를 "초기화 됨"상태로 설정하는 하나의 생성자가있는 객체가 있습니다. 그런 다음 그 인스턴스에서 "처리 된"상태로 가져 오는 메서드가 호출됩니다. "처리됨"상태를 갖는 새로운 객체를 생성하고 싶지는 않지만 여전히 인스턴스를 직렬화/비 직렬화해야합니다.

2) 개인 생성자와 일부 정적 속성을 사용하여 클래스를 생성하여 허용되는 생성자 매개 변수의 작은 집합을 제어했습니다. 이제는 그것들을 직렬화/직렬화 해제 할 수 있습니다.

XmlSerializer에는 예상 한 동작이 있습니다. 기본 생성자가 필요하기 때문에 XmlSerializer에 몇 가지 문제가있었습니다. 그와 관련하여 때로는 사유 재산 설정자를 갖는 것이 합리적입니다. 그러나 XmlSerializer는 serialize/deserialize하기 위해 속성에 대한 공용 getter 및 setter도 필요합니다.

직렬화 중에 인스턴스 상태를 일시 중단하고 deserialize 중에 다시 시작하는 것과 같은 DataContractSerializer/BinaryFormatter 동작을 생각합니다. 즉, 인스턴스는 "생성"되지 않고 초기 상태로 "복원"됩니다.

앞서 언급 한 것처럼 [OnDeserializing] 특성을 사용하면 직렬화되지 않은 데이터를 동기화 할 수 있습니다.

+0

나는 DataMember가 INotifyPropertyChanged를 사용하면서 생성자가 호출되지 않은 상태에서 NotifyPropertyChanged를 트리거하여 문제가 일시 중단되지 않도록 문제가 발생했기 때문에 "인스턴스 상태를 일시 중단"한다고 말하지 않습니다. – ForceMagic

관련 문제