2008-10-07 8 views
78

Il y a un peu de magie en cours avec la désérialisation de WCF. Comment instancier une instance du type de contrat de données sans appeler son constructeur?Comment la désérialisation de WCF instancie-t-elle des objets sans appeler un constructeur?

Par exemple, considérons ce contrat de données:

[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 
} 

Lors de l'obtention par DataContractSerializer une instance de cet objet, vous verrez que le champ _wasConstructorCalled est false.

Alors, comment WCF fait-il cela? Est-ce une technique que d'autres peuvent utiliser aussi, ou est-ce caché loin de nous?

Répondre

99

FormatterServices.GetUninitializedObject() va créer une instance sans appeler un constructeur. J'ai trouvé cette classe en utilisant Reflector et en explorant certaines classes de sérialisation .Net.

Je l'ai testé en utilisant le code exemple ci-dessous et il semble que ça fonctionne très bien:

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

Eh bien, j'ai déjà posté une mauvaise réponse (maintenant supprimé) alors je me sentais coupable. Rien de tel que d'écraser un ego de programmeurs pour l'amener à faire des recherches. –

+2

Est-ce que quelqu'un d'autre se demande maintenant, comment fonctionne FormatterServices.GetUninitializedObject, alors? Réflexion? – harpo

+0

Si je rappelle son appel en code natif. Je ne pouvais pas suivre ça plus loin dans le trou du lapin avec Reflector. –