Serialization and Inheritance in C#
What is Serialization in Inherited Classes?
Serialization in **inherited classes** allows a **derived class to be serialized**, including all properties and fields from its **base class**. Proper handling ensures that both **public and private members** of a base class are correctly serialized.
Key Features of Serialization in Inherited Classes
- The **[Serializable]** attribute must be applied to both **base and derived** classes.
- Base class **private fields are not serialized** unless explicitly handled.
- Use **ISerializable** for custom serialization of base class members.
- Supported in **Binary, XML, and JSON serialization**.
Basic Serialization with Inheritance
If a **base class is serializable**, all **public and protected members** are automatically serialized.
Example: Binary Serialization with Inheritance
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
[Serializable]
class Employee : Person
{
public int EmployeeID { get; set; }
}
// Writing Binary Data
class Program
{
static void Main()
{
Employee emp = new Employee { Name = "Alice", Age = 30, EmployeeID = 1001 };
BinaryFormatter formatter = new BinaryFormatter();
using (FileStream stream = new FileStream("employee.dat", FileMode.Create))
{
formatter.Serialize(stream, emp);
}
Console.WriteLine("Inherited class serialized successfully.");
}
}
// Output:
// Inherited class serialized successfully.
The **Employee** class inherits **Person**, and all **public and protected** fields are serialized.
Handling Private Fields in Base Class
Private members of a **base class** are **not automatically serialized** in derived classes.
Example: Custom Serialization for Private Fields
using System;
using System.IO;
using System.Runtime.Serialization;
[Serializable]
class Person
{
private string _secretCode = "1234";
public string Name { get; set; }
public int Age { get; set; }
public string GetSecretCode() => _secretCode;
}
[Serializable]
class Employee : Person
{
public int EmployeeID { get; set; }
}
// Writing Binary Data
class Program
{
static void Main()
{
Employee emp = new Employee { Name = "Bob", Age = 40, EmployeeID = 2001 };
IFormatter formatter = new BinaryFormatter();
using (FileStream stream = new FileStream("employee_secret.dat", FileMode.Create))
{
formatter.Serialize(stream, emp);
}
Console.WriteLine("Private fields in base class are NOT serialized.");
}
}
// Output:
// Private fields in base class are NOT serialized.
**Private fields** are not serialized automatically, but can be included using **ISerializable**.
Using ISerializable for Custom Serialization
Implementing **ISerializable** in the base class allows **full control over serialization**, including **private members**.
Example: Custom Serialization Using ISerializable
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
class Person : ISerializable
{
private string _secretCode = "9876";
public string Name { get; set; }
public int Age { get; set; }
public Person() { }
protected Person(SerializationInfo info, StreamingContext context)
{
_secretCode = info.GetString("SecretCode");
Name = info.GetString("Name");
Age = info.GetInt32("Age");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("SecretCode", _secretCode);
info.AddValue("Name", Name);
info.AddValue("Age", Age);
}
public string GetSecretCode() => _secretCode;
}
[Serializable]
class Employee : Person
{
public int EmployeeID { get; set; }
}
// Writing Binary Data
class Program
{
static void Main()
{
Employee emp = new Employee { Name = "Charlie", Age = 35, EmployeeID = 3001 };
BinaryFormatter formatter = new BinaryFormatter();
using (FileStream stream = new FileStream("employee_custom.dat", FileMode.Create))
{
formatter.Serialize(stream, emp);
}
Console.WriteLine("Private fields in base class are serialized using ISerializable.");
}
}
// Output:
// Private fields in base class are serialized using ISerializable.
Implementing **ISerializable** allows **custom serialization** of private fields.
Best Practices for Serialization in Inheritance
- Use **[Serializable]** for automatic serialization in both base and derived classes.
- Implement **ISerializable** in base classes to **serialize private fields**.
- For **XML and JSON serialization**, ensure **public properties** are properly defined.
- Handle **versioning carefully** when modifying serialized base class structures.