2008-10-07 4 views
78

WCF 직렬화로 진행되는 마술이 있습니다. 생성자를 호출하지 않고 데이터 계약 유형의 인스턴스를 어떻게 인스턴스화합니까? 당신이 필드 _wasConstructorCalledfalse 것을 볼 수 DataContractSerializer를 통해이 개체의 인스턴스를 취득 할 때WCF 역 직렬화는 생성자를 호출하지 않고 개체를 인스턴스화하는 방법은 무엇입니까?

[DataContract] 
public sealed class CreateMe 
{ 
    [DataMember] private readonly string _name; 
    [DataMember] private readonly int _age; 
    private readonly bool _wasConstructorCalled; 

    public CreateMe() 
    { 
     _wasConstructorCalled = true; 
    } 

    // ... other members here 
} 

:

예를 들어,이 데이터 계약을 고려한다.

그래서 WCF는 어떻게합니까? 이것은 다른 사람들이 사용할 수있는 기법입니까 아니면 우리에게서 숨겨져 있습니까?

답변

99

FormatterServices.GetUninitializedObject()은 생성자를 호출하지 않고 인스턴스를 만듭니다. Reflector을 사용하고 코어 .Net 직렬화 클래스 중 일부를 파헤어이 클래스를 찾았습니다.

나는 아래의 샘플 코드를 사용하여 테스트하고 잘 작동 것 같습니다 :

using System; 
using System.Reflection; 
using System.Runtime.Serialization; 

namespace NoConstructorThingy 
{ 
    class Program 
    { 
     static void Main() 
     { 
      // does not call ctor 
      var myClass = (MyClass)FormatterServices.GetUninitializedObject(typeof(MyClass)); 

      Console.WriteLine(myClass.One); // writes "0", constructor not called 
      Console.WriteLine(myClass.Two); // writes "0", field initializer not called 
     } 
    } 

    public class MyClass 
    { 
     public MyClass() 
     { 
      Console.WriteLine("MyClass ctor called."); 
      One = 1; 
     } 

     public int One { get; private set; } 
     public readonly int Two = 2; 
    } 
} 

http://d3j5vwomefv46c.cloudfront.net/photos/large/687556261.png

+5

글쎄, 이전에 잘못 대답 했으므로 (지금 삭제됨) 유죄로 느꼈습니다. 프로그래머의 자존심에 타박상을 입혀 연구를 해보는 것만 큼 아무 것도 없습니다. –

+2

이제는 궁금한 사람이 있습니까? FormatterServices.GetUninitializedObject가 어떻게 작동합니까? 반사? – harpo

+0

전화를 원래 코드로 되 돌리면. 리플렉터로 토끼 구멍을 내려 가면 이걸 따라갈 수 없었습니다. –

관련 문제