Чтобы понять это поведение, я добавил еще один контрольный пример:
var input =
"using MyUsing1;\r\n" +
"#if CONDITIONAL\r\n" +
"using MyUsing2;\r\n" +
"#endif" +
"using MyUsing3;\r\n";
string result = Process(input, new[] { "CONDITIONAL" });
И в этом случае, #if
и #endif
сохраняются.
Если вы остановитесь в отладчике и посмотрите на массив usings
, кажется, что каждый UsingDirectiveSyntax
знает как минимальный диапазон символов для оператора using
(Span
), так и "более широкий" диапазон символы из исходного потока (FullSpan
), который включает в себя такие вещи, как, в данном случае, директива #if
.
Копая немного глубже, документы ссылаются на предыдущий код, такой как директива preproc, как на "ведущие мелочи", и он присоединен к узлу использования как дочерний.
Интересно, что если вы передадите .AddUsings()
только одну из директив using, то, похоже, пропущены начальные мелочи; но если вы дадите ему массив, кратный UsingDirectiveSyntax
с, то для каждого, кроме первого, он будет содержать начальные пустяки. (Это, вероятно, не совсем верно; я работаю только из наблюдений черного ящика.)
Я не собираюсь притворяться, что понимаю причину такого поведения. В результате многие биты кода, которые выглядят нормально - как ваш пример - будут вызывать тревожные результаты. (Если вы передадите new[] {usings[0], usings[2], usings[1]}
, вы получите еще худший результат, с #endif
перед #if
. Но ... вы знаете ... Я думаю, зачем вам это делать?)
Так что, если вы хотите использовать эти инструменты для генерации исходного кода, который будет возвращаться в полный конвейер сборки, вы можете увидеть это как ошибку (или, по крайней мере, странное поведение, которое может легко стать источником ошибок). Если есть предполагаемое использование, которое поможет вам избежать этого, я не могу найти прямую документацию об этом. В этом случае вы можете удалить мелочи из usings
перед добавлением их в вывод; но в других случаях это может привести к тому, что вы захотите сохранить то, что я думаю.