Вы можете использовать Microsoft.CodeAnalysis.CSharp.SyntaxFactory для создания Microsoft.CodeAnalysis.SyntaxNode
.<75735286>.
Чтобы получить код фабрики синтаксиса, необходимый для создания новых синтаксических деревьев, взгляните на фантастический RoslynQuoter.
Там вы можете поместить программу C#, которую хотите создать, с помощью API фабрики синтаксиса:
.
public class RoslynClass
{
public static int RoslynMethod(int left, int right)
{
return left + right;
}
}
Отметьте все параметры по своему усмотрению и Получите вызовы Roslyn API для создания этого кода!, который вы можете (частично) использовать в своем производственном коде.
Здесь я перечисляю пример A Рефакторинг исходного кода , который вводит метод public static int RoslynMethod(int left, int right)
До/после любого A Field <77392065355555555929992923353535298> Field <7739206535355555555929929239235355298>.
>
using System.Composition;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Editing;
namespace RoslynTool
{
[ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = nameof(MethodInserter))]
[Shared]
internal sealed class MethodInserter : CodeRefactoringProvider
{
public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
{
SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
SyntaxNode node = root.FindNode(context.Span);
if (node is FieldDeclarationSyntax or MethodDeclarationSyntax)
{
SyntaxNode newNode = CreateMethodNode();
context.RegisterRefactoring(CodeAction.Create("Insert method before", ct => InsertBeforeAsync(context.Document, node, newNode, ct)));
context.RegisterRefactoring(CodeAction.Create("Insert method after", ct => InsertAfterAsync(context.Document, node, newNode, ct)));
}
}
private static MemberDeclarationSyntax CreateMethodNode()
{
return SyntaxFactory.MethodDeclaration(
SyntaxFactory.PredefinedType(
SyntaxFactory.Token(SyntaxKind.IntKeyword)),
SyntaxFactory.Identifier("RoslynMethod"))
.WithModifiers(
SyntaxFactory.TokenList(new[] {
SyntaxFactory.Token(SyntaxKind.PublicKeyword),
SyntaxFactory.Token(SyntaxKind.StaticKeyword)}))
.WithParameterList(
SyntaxFactory.ParameterList(
SyntaxFactory.SeparatedList<ParameterSyntax>(new SyntaxNodeOrToken[] {
SyntaxFactory.Parameter(
SyntaxFactory.Identifier("left"))
.WithType(
SyntaxFactory.PredefinedType(
SyntaxFactory.Token(SyntaxKind.IntKeyword))),
SyntaxFactory.Token(SyntaxKind.CommaToken),
SyntaxFactory.Parameter(
SyntaxFactory.Identifier("right"))
.WithType(
SyntaxFactory.PredefinedType(
SyntaxFactory.Token(SyntaxKind.IntKeyword)))})))
.WithBody(
SyntaxFactory.Block(
SyntaxFactory.SingletonList<StatementSyntax>(
SyntaxFactory.ReturnStatement(
SyntaxFactory.BinaryExpression(
SyntaxKind.AddExpression,
SyntaxFactory.IdentifierName("left"),
SyntaxFactory.IdentifierName("right"))))));
}
private static async Task<Document> InsertBeforeAsync(Document document, SyntaxNode location, SyntaxNode newNode, CancellationToken cancellationToken)
{
DocumentEditor documentEditor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
documentEditor.InsertBefore(location, newNode);
return documentEditor.GetChangedDocument();
}
private static async Task<Document> InsertAfterAsync(Document document, SyntaxNode location, SyntaxNode newNode, CancellationToken cancellationToken)
{
DocumentEditor documentEditor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
documentEditor.InsertAfter(location, newNode);
return documentEditor.GetChangedDocument();
}
}
}

Альтернативно, PARSE SyntaxFactory можно использовать для создания нового hald -haldode, чтобы создать новый > haldode, чтобы быть использованным. пример:
namespace RoslynTool
{
internal sealed class MethodInserter : CodeRefactoringProvider
{
private static MemberDeclarationSyntax CreateMethodNode()
{
return SyntaxFactory.ParseMemberDeclaration(@"
public static int RoslynMethod(int left, int right)
{
return left + right;
}
");
}
}
}
Надеюсь, я правильно понял ваш вопрос.
Я не уверен, соответствует ли это моим требованиям, так как все нужно делать во время выполнения, я хочу использовать RoselynAPI для преобразования источника ресурсов, который будет создан во время выполнения. Кроме того, поскольку методы, которые нужно вставить, заранее неизвестны, я не могу преобразовать их в C# RoslynMethod. Мне нужно поместить их как «текст» или разобрать из текста. В любом случае спасибо за помощь
@0x0000000000000 Является ли ресурс, из которого вы хотите сгенерировать код C#, доступным только во время выполнения или уже полностью доступным во время компиляции? Поскольку, если ресурс уже известен во время компиляции и вы используете пакет SDK для .NET 5.0 (или более позднюю версию), то, возможно, генераторы исходного кода могут вам помочь. Предупреждение здесь заключается в том, что вы не можете вставлять какой-либо новый код в существующие файлы, а вместо этого помечаете свой тип как
partial
, а затем «расширяете» его с помощью генератора исходного кода во времяdotnet build
.Поток на самом деле таков: получение исходного кода из встроенного файла ресурсов (.CS), модификация во время выполнения (мы здесь), а затем компиляция кода во время выполнения с использованием поставщика CSharpCode. Ресурс получается в виде строки, это обычный источник CS. Все делается, кроме модификации во время выполнения с помощью Roselyn. Для вставленного кода МЫ не знаем его заранее, но МЫ также получаем его как строку.
Поскольку на самом деле никто другой не предлагает более точного решения моей проблемы, я скоро наградю вас, если никто не ответит.
@ 0x0000000000000 Боюсь, я не совсем знаком с генерацией кода во время выполнения. Я умею генерировать код во время разработки с помощью исправлений/рефакторингов кода, а также генерировать код во время компиляции с помощью генераторов исходного кода, но у меня очень мало опыта с генерацией кода во время выполнения . Извини.