In-depth Analysis of Object Serialization to String in C#: Complete Implementation from XML to JSON

Nov 15, 2025 · Programming · 11 views · 7.8

Keywords: C# Serialization | XML Serialization | JSON Serialization | StringWriter | System.Text.Json

Abstract: This article provides a comprehensive exploration of object serialization to string in C#, focusing on the core principles of using StringWriter instead of StreamWriter for XML serialization. It explains in detail the critical differences between toSerialize.GetType() and typeof(T) in XmlSerializer construction. The article also extends to JSON serialization methods in the System.Text.Json namespace, covering synchronous/asynchronous serialization, formatted output, UTF-8 optimization, and other advanced features. Through complete code examples and performance comparisons, it offers developers comprehensive serialization solutions.

Fundamental XML Serialization Implementation

In C# development, object serialization is a core technology for data persistence and network transmission. The original file serialization method uses StreamWriter to write objects to disk files:

// Save object to disk file
public static void SerializeObject<T>(this T toSerialize, String filename)
{
    XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
    TextWriter textWriter = new StreamWriter(filename);

    xmlSerializer.Serialize(textWriter, toSerialize);
    textWriter.Close();
}

Optimized Solution for String Output

When serialization results need to be returned as strings rather than saved to files, using StringWriter instead of StreamWriter is the optimal solution:

public static string SerializeObject<T>(this T toSerialize)
{
    XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());

    using(StringWriter textWriter = new StringWriter())
    {
        xmlSerializer.Serialize(textWriter, toSerialize);
        return textWriter.ToString();
    }
}

Key improvements in this implementation include:

Deep Principles of Type Handling

In the XmlSerializer constructor, using toSerialize.GetType() instead of typeof(T) has significant technical implications:

// Correct: Supports all derived types of T
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());

// Incorrect: Throws exceptions when passing derived type instances
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

This distinction stems from the runtime behavior of C#'s generic type system. toSerialize.GetType() returns the actual runtime type of the object, properly handling all subclasses in the inheritance hierarchy. typeof(T) is determined at compile time, and when the method receives instances of derived classes, XmlSerializer cannot recognize the actual serialization type, causing runtime exceptions.

Modern JSON Serialization Solutions

With the popularity of Web APIs and microservices architecture, JSON has become a more prevalent serialization format. The System.Text.Json namespace provides high-performance JSON serialization support.

Basic Serialization Implementation

using System.Text.Json;

public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}

// Synchronous serialization to string
string jsonString = JsonSerializer.Serialize(weatherForecast);

// Explicitly specifying generic type parameters
string jsonString = JsonSerializer.Serialize<WeatherForecast>(weatherForecast);

File Serialization Operations

// Synchronous file writing
string fileName = "WeatherForecast.json";
string jsonString = JsonSerializer.Serialize(weatherForecast);
File.WriteAllText(fileName, jsonString);

// Asynchronous file writing (recommended for I/O-intensive operations)
await using FileStream createStream = File.Create(fileName);
await JsonSerializer.SerializeAsync(createStream, weatherForecast);

Advanced Serialization Features

Formatted Output Configuration

var options = new JsonSerializerOptions { WriteIndented = true };
string jsonString = JsonSerializer.Serialize(weatherForecast, options);

// Output result:
// {
//   "Date": "2019-08-01T00:00:00-07:00",
//   "TemperatureCelsius": 25,
//   "Summary": "Hot"
// }

UTF-8 Performance Optimization

For performance-sensitive scenarios, direct serialization to UTF-8 byte arrays is 5-10% faster than string methods:

byte[] jsonUtf8Bytes = JsonSerializer.SerializeToUtf8Bytes(weatherForecast);

Complex Object Serialization

public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
    public string? SummaryField;
    public IList<DateTimeOffset>? DatesAvailable { get; set; }
    public Dictionary<string, HighLowTemps>? TemperatureRanges { get; set; }
    public string[]? SummaryWords { get; set; }
}

public class HighLowTemps
{
    public int High { get; set; }
    public int Low { get; set; }
}

Serialization Behavior Control

System.Text.Json provides rich serialization behavior configuration:

Technical Selection Recommendations

When choosing serialization solutions, consider the following factors:

By deeply understanding the principles and characteristics of different serialization technologies, developers can select optimal solutions based on specific requirements and build efficient and reliable data processing systems.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.