Singleton

Manual implementation of a thread-safe Singleton without using Lazy<T>.

#When to use it

When you need fine-grained control over initialization (e.g., parameters only known at runtime) and Lazy<T> does not fit.

#C# Example

public sealed class Cache
{
    private static Cache? _instance;
    private static readonly object _gate = new();

    public static Cache Instance
    {
        get
        {
            if (_instance is null)
            {
                lock (_gate)
                {
                    _instance ??= new Cache();
                }
            }
            return _instance;
        }
    }

    private Cache() { /* costly initialization */ }
}
When NOT to use it

If you don't need conditional initialization, prefer Lazy<T> — it's more readable and just as safe.

#creational #threading #lock