2013-03-04 2 views
3

저는 지난 몇 시간 동안 'No parameterless constructor found for [type]' 예외로 고생했습니다. 이제는 응용 프로그램에서 얻은 것을 미러링해야하는 간단한 단위 테스트를 만들었습니다. 수행하지 않으면이 예외가 throw 된 것 같습니다. stream.Position = 0.스트림 끝을지나 읽을 때 매개 변수없는 생성자 예외가 발생하지 않습니다.

또한 어떤 경우에도 객체가 표준 클래스 (추상 클래스에서 파생되지 않음) 일 때이 예외가 발생하지 않습니다.

아래의 코드를 참조하십시오 :있는 그대로가

  1. 실행 -이 생성자는 자료

    를 찾을 수 없습니다 말하는 깰 것이
  2. 주석 stream.Position = 0 및 괜찮을 것

  3. 덧글 라인을 다시 주석으로, 파생 클래스를 기본에서 상속하지 않도록 변경하고 클래스의 유일한 속성의 주석 처리를 제거하고 실행합니다. 중단되지는 않지만 (분명히 이름은 null이됩니다)

왜 이런 식으로 작동하는지 설명 할 수 있습니까? 왜 # 1이 던 졌는가 (왜 # 3이 아닌가?) 왜이 메시지를 던집니까?

[Test] 
public void CanSerialize_Derived() 
{ 
    var derived = new Derived() {Name = "ngf"}; 
    var stream = new MemoryStream(); 
    Serializer.Serialize(stream, derived); 
    //stream.Position = 0; 
    var deserializedInstance = Serializer.Deserialize<Derived>(stream); 
} 

[ProtoContract] 
[ProtoInclude(9, typeof(Derived))] 
public abstract class Base 
{ 
    [ProtoMember(1)] 
    public string Name { get; set; } 
} 

[ProtoContract] 
public class Derived : Base 
{ 
    //[ProtoMember(1)] 
    //public string Name { get; set; } 
} 

답변

5

길이가 0 인 스트림은 protobuf-net에서 유효합니다. protobuf-net에서 모든 직렬화는 해당 DTO 상속 트리의 루트 유형에서 시작하므로 은 Base에서 시작하고 이 실제로 데이터에 Derived이 포함될 때까지 믿을 수 없습니다. Base으로 해보십시오. 그래서 # 1이 던졌습니다.

마지막으로 스트림을 나가면 분명히 직렬화 할 수있는 데이터 길이는 0입니다. 그래서 # 2가 통과합니다.

상속을 제거하면 해당 상속 트리의 루트는 Derived입니다. 이는 근본적으로 큰 변화이지만, 상속이라는 측면에서 차이점은 어떤 정보도없이 abstract 유형을 비 직렬화하려고하지 않는다는 것입니다. 그래서 # 3은 그것을 (왜곡 된 이유로) 고쳐줍니다.

여기에서 중요한 점은 상속이으로 구현 된 입니다. 정보가 없다면 오브젝트가 상속 트리의 루트에있는 유형이라고 가정하는 유일한 것입니다.

+0

설명 해 주셔서 감사합니다. 실제로 동작이 더 현실적으로 이루어집니다. –

관련 문제