How does WCF deserialization instantiate objects without calling a constructor?
Solution 1
FormatterServices.GetUninitializedObject()
will create an instance without calling a constructor. I found this class by using Reflector and digging through some of the core .Net serialization classes.
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
Solution 2
Yes, FormatterServices.GetUninitializedObject() is the source of the magic.
If you want to do any special initialization, see this. http://blogs.msdn.com/drnick/archive/2007/11/19/serialization-and-types.aspx
Related videos on Youtube
Comments
-
Drew Noakes about 4 years
There is some magic going on with WCF deserialization. How does it instantiate an instance of the data contract type without calling its constructor?
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
DataContractSerializer
you will see that the field_wasConstructorCalled
isfalse
.So, how does WCF do this? Is this a technique that others can use too, or is it hidden away from us?
-
Jason Jackson over 15 yearsWell, I previously posted a wrong answer (now deleted) so I felt guilty. Nothing like bruising a programmers ego to get him to do some research.
-
harpo almost 14 yearsIs anyone else now wondering, how does FormatterServices.GetUninitializedObject work, then? Reflection?
-
Jason Jackson almost 14 yearsIf I recall its a call into native code. I couldn't follow this any farther down the rabbit hole with Reflector.
-
bushed over 12 yearsWeird - I run that code in linqpad and I got: 0 0 as output. Actually that makes sense to me since field initializers are inlined into ctors AFAIK
-
Oliver over 11 years@bushed is correct. I've posted a screenshot with the code and result here. At first I thought it might be a difference in the .NET framework versions (since the answer is already 4 years old) but I checked for 2.0 and 4.0 and they both write 0 and 0 to the console. Jason Jackson, Could you update your post to reflect these findings?
-
bas over 9 years+1 for the reference,
[OnDeserialized]
was the solution for me!