WCF
deserialization
object instantiation
constructors
.NET framework

How does WCF deserialization instantiate objects without calling a constructor?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

WCF deserialization can create objects without running their normal constructors. That behavior feels surprising at first, but it exists so the serializer can rebuild object state directly from serialized data without triggering arbitrary constructor side effects.

Why constructors are skipped

During deserialization, the serializer already has the data needed to populate the object. Calling a constructor first would be risky because constructors often open files, register events, allocate resources, or enforce rules intended only for fresh objects.

Instead, serializers in the .NET ecosystem can allocate an instance in a lower-level way and then populate fields or properties afterward. In practice, this often involves runtime services that create an uninitialized object and then hydrate it.

That is why deserialization is not the same thing as "call the constructor and then copy values in." It is closer to "allocate the instance shell, then restore the serialized state."

What this means in WCF

WCF commonly uses DataContractSerializer. When it reconstructs a type, it can materialize the object without invoking the usual constructor path. The object is then populated from the serialized members defined by the data contract.

This has an important consequence: constructor logic and field initializers are not reliable places for deserialization-time invariants. If your object must restore derived state after deserialization, use the serializer callback attributes instead.

csharp
1using System;
2using System.Runtime.Serialization;
3
4[DataContract]
5public class UserProfile
6{
7    [DataMember]
8    public string Name { get; set; } = "";
9
10    [IgnoreDataMember]
11    public string DisplayName { get; private set; } = "";
12
13    public UserProfile()
14    {
15        Console.WriteLine("Constructor ran");
16        DisplayName = "fresh object";
17    }
18
19    [OnDeserialized]
20    private void OnDeserialized(StreamingContext context)
21    {
22        DisplayName = $"User: {Name}";
23    }
24}

In a normal constructor path, DisplayName starts as "fresh object". During deserialization, the constructor may be bypassed, so the correct place to rebuild DisplayName is the OnDeserialized method.

Why this design is useful

Skipping constructors keeps deserialization deterministic. The serializer can restore data without accidentally running logic that depends on current environment state, external services, or assumptions meant only for brand-new instances.

It also allows types to be deserialized even when their constructors are inconvenient for the serializer. That does not mean every type is a good serialization candidate, but it explains why the runtime uses a different instantiation path than ordinary new.

Design your types with deserialization in mind

If a class has invariants that must always hold, make sure they can be re-established after the members are populated. In WCF and related serializers, callback attributes such as OnDeserializing and OnDeserialized are the right hooks for this.

Avoid relying on constructors for validation that must also hold after deserialization. If invalid serialized data is possible, validate after the object is hydrated, not only when it is freshly constructed in application code.

The deeper lesson is that serialization boundaries are special lifecycle moments. They are not ordinary object creation.

Common Pitfalls

  • Assuming a constructor will always run when WCF recreates an object.
  • Putting essential derived-state initialization only in field initializers or constructors.
  • Using constructors for side effects that make no sense during deserialization.
  • Forgetting deserialization callback hooks when the object needs post-load repair work.
  • Treating deserialized instances as if they were built through the exact same path as new.

Summary

  • WCF deserialization can allocate objects without invoking their normal constructors.
  • This avoids constructor side effects and lets the serializer restore state directly.
  • 'DataContractSerializer populates members after the instance shell is created.'
  • Use deserialization callbacks such as OnDeserialized for derived-state repair and validation.
  • Design serialized types with the understanding that deserialization is not ordinary object construction.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.