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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/178645/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:46:28  来源:igfitidea点击:

How does WCF deserialization instantiate objects without calling a constructor?

c#.netwcfreflectionserialization

提问by Drew Noakes

There is some magic going on with WCF deserialization. How does it instantiate an instance of the data contract type without calling its constructor?

WCF 反序列化有一些神奇之处。它如何在不调用其构造函数的情况下实例化数据协定类型的实例?

For example, consider this data contract:

例如,考虑这个数据契约:

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

When obtaining an instance of this object via DataContractSerializeryou will see that the field _wasConstructorCalledis false.

通过获取此对象的实例时,DataContractSerializer您将看到该字段_wasConstructorCalledfalse

So, how does WCF do this? Is this a technique that others can use too, or is it hidden away from us?

那么,WCF 是如何做到这一点的呢?这是其他人也可以使用的技术,还是隐藏在我们之外?

采纳答案by Jason Hymanson

FormatterServices.GetUninitializedObject()will create an instance without calling a constructor. I found this class by using Reflectorand digging through some of the core .Net serialization classes.

FormatterServices.GetUninitializedObject()将创建一个实例而不调用构造函数。我通过使用Reflector和挖掘一些核心 .Net 序列化类找到了这个类。

I tested it using the sample code below and it looks like it works great:

我使用下面的示例代码对其进行了测试,看起来效果很好:

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

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

回答by AaronM

Yes, FormatterServices.GetUninitializedObject() is the source of the magic.

是的,FormatterServices.GetUninitializedObject() 是魔法的源泉。

If you want to do any special initialization, see this. http://blogs.msdn.com/drnick/archive/2007/11/19/serialization-and-types.aspx

如果你想做任何特殊的初始化,请看这里。 http://blogs.msdn.com/drnick/archive/2007/11/19/serialization-and-types.aspx