Я не уверен, что это относится и к C #, но я отвечу за C ++:
Одна из идей синглетонов заключается в том, что порядок инициализации статических объектов не определен. Так что если у вас есть статический класс, который пытается использовать другой статический класс, у вас могут быть проблемы.
Конкретный пример: допустим, у меня есть класс Log, который я решил реализовать как Singleton. Давайте также предположим, что у меня есть метод с именем LoadDB, который по какой-то причине является статическим, вызываемым в начале программы. Предполагая, что LoadDB решит, что ему нужно что-то записать, он вызовет Singleton. Но так как порядок статической инициализации не определен, возможно, он делает что-то, что является ошибкой.
Синглтон исправляет это, поскольку после вызова GetInstance (), независимо от того, где вы находитесь в процессе инициализации, объект гарантированно существует.
Опять же, я не знаю, относится ли это к делу, но, по крайней мере, это история (насколько я помню).