C’è un po ‘di magia in corso con la deserializzazione della WCF. Come crea un’istanza del tipo di contratto dati senza chiamare il suo costruttore?
Ad esempio, considera questo contratto di dati:
[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 }
Quando _wasConstructorCalled
un’istanza di questo object tramite DataContractSerializer
, vedrai che il campo _wasConstructorCalled
è false
.
Quindi, come fa la WCF a fare questo? È una tecnica che anche altri possono usare o è nascosta a noi?
FormatterServices.GetUninitializedObject()
creerà un’istanza senza chiamare un costruttore. Ho trovato questa class usando Reflector e scavando attraverso alcune delle classi di serializzazione .NET.
L’ho provato usando il codice di esempio qui sotto e sembra che funzioni alla grande:
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; } }
Sì, FormatterServices.GetUninitializedObject () è la fonte della magia.
Se vuoi fare un’inizializzazione speciale, vedi questo. http://blogs.msdn.com/drnick/archive/2007/11/19/serialization-and-types.aspx