Кажется, что проблема связана с инициализацией вложенных статических классов перед их родителем. См. Пример ниже, я включил комментарии, чтобы указать порядок, в котором я ожидал, что вещи будут инициализированы/вызваны, и фактический порядок. В этом случае я звоню Test1.Test2.GetName()
, поэтому я ожидал, что статические классы инициализируются в следующем порядке: Test1
, Test2
Вложенные статические классы, инициализированные в неправильном порядке?
using System;
using System.Collections.Generic;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
Console.WriteLine(Test1.Test2.GetName());
Console.ReadKey();
}
}
public static class Test1 {
// Actual Order: 2; Expected: 1
private static string Name = "Test1";
public static List<string> Names { get; private set; }
// Actual Order: 3; Expected: 2
static Test1() {
Test1.Names = new List<string>(new string[] {
Test2.GetName()
});
}
public static class Test2 {
// Actual Order: 1; Expected: 3
private static string Name = Test1.Name.ToString() + "_Test2";
// Actual Order: 4; Expected: 4
public static string GetName() {
return Name.ToString();
}
}
}
}
Я думал, что статика инициализирована в первый раз был прикоснулся класс, но, видимо, прикасаясь вложенным класс сначала не инициализирует родителя! Для меня это похоже на ошибку. Это делает это:
Test2.Name
->Test1.Name
->Test1()
->Test2.GetName()
->Test2.Name
Таким образом, хотя Test2.Name
является точкой входа, в теории, не инициализируются времени это необходимо.
Хорошо освещенный в [литература] (https://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx). Цитата: «Пользователь не имеет контроля над тем, когда статический конструктор выполняется в программе». Другими словами, порядок не является «неправильным», он не определен. –
Он также говорит: «вызывается автоматически до создания первого экземпляра или ссылки на какие-либо статические члены», что в этом случае неверно, так как сначала инициализирован вложенный статический класс! Я не ожидаю, что у меня будет контроль, но я должен принять порядок, в котором это произойдет. –
Вместо этого вы должны полагаться на методы инициализации. Таким образом вы контролируете инициализацию. В худшем случае вы можете инициализировать их из статического конструктора в программе. – Bauss