代码之家  ›  专栏  ›  技术社区  ›  Drew Noakes

WCF反序列化如何在不调用构造函数的情况下实例化对象?

  •  78
  • Drew Noakes  · 技术社区  · 16 年前

    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
    }
    

    通过获取此对象的实例时 DataContractSerializer 你会看到那块地 _wasConstructorCalled false .

    那么,WCF是如何做到的呢?这是别人也可以使用的一种技术,还是它对我们隐藏?

    2 回复  |  直到 10 年前
        1
  •  100
  •   Drew Noakes    11 年前

    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

        2
  •  19
  •   AaronM    14 年前

    是的,FormatterServices.GetUninitializedObject()是魔力的来源。

    如果您想进行任何特殊的初始化,请参见。 http://blogs.msdn.com/drnick/archive/2007/11/19/serialization-and-types.aspx