Skip to content

SyntaxFactory 基础

📋 文档信息

难度: 🟡 中级
预计阅读时间: 25 分钟
前置知识:

  • C# 基础语法
  • Roslyn 基本概念
  • 语法树基础知识

适合人群:

  • 需要生成 C# 代码的开发者
  • 源生成器开发者
  • 代码分析工具开发者

📋 快速导航

章节难度阅读时间链接
基本概念🟢3 分钟查看
常用方法🟡15 分钟查看
完整示例🟡7 分钟查看

🎯 概览

SyntaxFactory 是 Roslyn 提供的用于创建语法节点的工厂类。它提供了创建各种 C# 语法元素的静态方法。

本文档涵盖:

  • SyntaxFactory 的基本概念
  • 创建类型、表达式和语句的方法
  • 完整的代码生成示例

典型应用场景:

  • 生成简单的类和属性
  • 创建方法和语句
  • 构建基本的代码结构

基本概念

SyntaxFactory 是 Roslyn 提供的用于创建语法节点的工厂类。它提供了创建各种 C# 语法元素的静态方法。

csharp
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

/// <summary>
/// SyntaxFactory 基础示例
/// </summary>
public class SyntaxFactoryBasics
{
    /// <summary>
    /// 创建简单的标识符
    /// </summary>
    public IdentifierNameSyntax CreateIdentifier()
    {
        // 创建标识符:myVariable
        return IdentifierName("myVariable");
    }
    
    /// <summary>
    /// 创建字面量
    /// </summary>
    public LiteralExpressionSyntax CreateLiteral()
    {
        // 创建整数字面量:42
        return LiteralExpression(
            SyntaxKind.NumericLiteralExpression,
            Literal(42));
    }
    
    /// <summary>
    /// 创建字符串字面量
    /// </summary>
    public LiteralExpressionSyntax CreateStringLiteral()
    {
        // 创建字符串字面量:"Hello, World!"
        return LiteralExpression(
            SyntaxKind.StringLiteralExpression,
            Literal("Hello, World!"));
    }
}

常用方法

1. 创建类型

csharp
/// <summary>
/// 创建各种类型语法
/// </summary>
public class TypeCreation
{
    /// <summary>
    /// 创建预定义类型(int, string 等)
    /// </summary>
    public PredefinedTypeSyntax CreatePredefinedType()
    {
        // 创建 int 类型
        return PredefinedType(Token(SyntaxKind.IntKeyword));
    }
    
    /// <summary>
    /// 创建自定义类型
    /// </summary>
    public IdentifierNameSyntax CreateCustomType()
    {
        // 创建 MyClass 类型
        return IdentifierName("MyClass");
    }
    
    /// <summary>
    /// 创建泛型类型
    /// </summary>
    public GenericNameSyntax CreateGenericType()
    {
        // 创建 List<int> 类型
        return GenericName(
            Identifier("List"),
            TypeArgumentList(
                SingletonSeparatedList<TypeSyntax>(
                    PredefinedType(Token(SyntaxKind.IntKeyword)))));
    }
    
    /// <summary>
    /// 创建数组类型
    /// </summary>
    public ArrayTypeSyntax CreateArrayType()
    {
        // 创建 int[] 类型
        return ArrayType(
            PredefinedType(Token(SyntaxKind.IntKeyword)),
            SingletonList(
                ArrayRankSpecifier(
                    SingletonSeparatedList<ExpressionSyntax>(
                        OmittedArraySizeExpression()))));
    }
    
    /// <summary>
    /// 创建可空类型
    /// </summary>
    public NullableTypeSyntax CreateNullableType()
    {
        // 创建 int? 类型
        return NullableType(
            PredefinedType(Token(SyntaxKind.IntKeyword)));
    }
}

2. 创建表达式

csharp
/// <summary>
/// 创建各种表达式
/// </summary>
public class ExpressionCreation
{
    /// <summary>
    /// 创建二元表达式
    /// </summary>
    public BinaryExpressionSyntax CreateBinaryExpression()
    {
        // 创建:a + b
        return BinaryExpression(
            SyntaxKind.AddExpression,
            IdentifierName("a"),
            IdentifierName("b"));
    }
    
    /// <summary>
    /// 创建方法调用
    /// </summary>
    public InvocationExpressionSyntax CreateMethodCall()
    {
        // 创建:Console.WriteLine("Hello")
        return InvocationExpression(
            MemberAccessExpression(
                SyntaxKind.SimpleMemberAccessExpression,
                IdentifierName("Console"),
                IdentifierName("WriteLine")),
            ArgumentList(
                SingletonSeparatedList(
                    Argument(
                        LiteralExpression(
                            SyntaxKind.StringLiteralExpression,
                            Literal("Hello"))))));
    }
    
    /// <summary>
    /// 创建对象创建表达式
    /// </summary>
    public ObjectCreationExpressionSyntax CreateObjectCreation()
    {
        // 创建:new MyClass()
        return ObjectCreationExpression(
            IdentifierName("MyClass"),
            ArgumentList(),
            null);
    }
    
    /// <summary>
    /// 创建成员访问表达式
    /// </summary>
    public MemberAccessExpressionSyntax CreateMemberAccess()
    {
        // 创建:obj.Property
        return MemberAccessExpression(
            SyntaxKind.SimpleMemberAccessExpression,
            IdentifierName("obj"),
            IdentifierName("Property"));
    }
}

3. 创建语句

csharp
/// <summary>
/// 创建各种语句
/// </summary>
public class StatementCreation
{
    /// <summary>
    /// 创建变量声明语句
    /// </summary>
    public LocalDeclarationStatementSyntax CreateVariableDeclaration()
    {
        // 创建:int x = 42;
        return LocalDeclarationStatement(
            VariableDeclaration(
                PredefinedType(Token(SyntaxKind.IntKeyword)),
                SingletonSeparatedList(
                    VariableDeclarator(
                        Identifier("x"),
                        null,
                        EqualsValueClause(
                            LiteralExpression(
                                SyntaxKind.NumericLiteralExpression,
                                Literal(42)))))));
    }
    
    /// <summary>
    /// 创建 return 语句
    /// </summary>
    public ReturnStatementSyntax CreateReturnStatement()
    {
        // 创建:return 42;
        return ReturnStatement(
            LiteralExpression(
                SyntaxKind.NumericLiteralExpression,
                Literal(42)));
    }
    
    /// <summary>
    /// 创建 if 语句
    /// </summary>
    public IfStatementSyntax CreateIfStatement()
    {
        // 创建:if (x > 0) { return true; }
        return IfStatement(
            BinaryExpression(
                SyntaxKind.GreaterThanExpression,
                IdentifierName("x"),
                LiteralExpression(
                    SyntaxKind.NumericLiteralExpression,
                    Literal(0))),
            Block(
                ReturnStatement(
                    LiteralExpression(
                        SyntaxKind.TrueLiteralExpression))));
    }
}

SyntaxFactory 完整示例

csharp
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

/// <summary>
/// 使用 SyntaxFactory 生成完整的类
/// </summary>
public class CompleteClassGeneration
{
    /// <summary>
    /// 生成一个简单的类
    /// </summary>
    public ClassDeclarationSyntax GenerateSimpleClass()
    {
        // 生成:
        // public class Person
        // {
        //     public string Name { get; set; }
        //     public int Age { get; set; }
        // }
        
        return ClassDeclaration("Person")
            .AddModifiers(Token(SyntaxKind.PublicKeyword))
            .AddMembers(
                // Name 属性
                PropertyDeclaration(
                    PredefinedType(Token(SyntaxKind.StringKeyword)),
                    Identifier("Name"))
                .AddModifiers(Token(SyntaxKind.PublicKeyword))
                .AddAccessorListAccessors(
                    AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                        .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
                    AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                        .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))),
                
                // Age 属性
                PropertyDeclaration(
                    PredefinedType(Token(SyntaxKind.IntKeyword)),
                    Identifier("Age"))
                .AddModifiers(Token(SyntaxKind.PublicKeyword))
                .AddAccessorListAccessors(
                    AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                        .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
                    AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                        .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))));
    }
}

💡 最佳实践

实践 1: 使用 using static 简化代码

csharp
// ✅ 好:使用 using static
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

var property = PropertyDeclaration(...);

// ❌ 差:每次都写完整类名
var property = SyntaxFactory.PropertyDeclaration(...);

原因: 使用 using static 可以让代码更简洁,提高可读性。

实践 2: 使用 Add* 方法链式调用

csharp
// ✅ 好:使用链式调用
var classDecl = ClassDeclaration("MyClass")
    .AddModifiers(Token(SyntaxKind.PublicKeyword))
    .AddMembers(property1, property2, method1);

// ❌ 差:分步添加
var classDecl = ClassDeclaration("MyClass");
classDecl = classDecl.AddModifiers(Token(SyntaxKind.PublicKeyword));
classDecl = classDecl.AddMembers(property1);
classDecl = classDecl.AddMembers(property2);
classDecl = classDecl.AddMembers(method1);

原因: 链式调用更简洁,代码更易读。

实践 3: 使用 NormalizeWhitespace 格式化代码

csharp
// ✅ 好:使用 NormalizeWhitespace 格式化
var code = classDecl.NormalizeWhitespace().ToFullString();

// ❌ 差:不格式化
var code = classDecl.ToFullString();

原因: 自动格式化代码,使其更易读。


⚠️ 常见错误

错误 1: 忘记添加分号标记

问题: 生成的语句缺少分号。

csharp
// ❌ 错误:缺少分号
var accessor = AccessorDeclaration(SyntaxKind.GetAccessorDeclaration);

解决方案: 使用 WithSemicolonToken 添加分号。

csharp
// ✅ 正确:添加分号
var accessor = AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));

错误 2: 忘记格式化代码

问题: 生成的代码没有格式化,难以阅读。

csharp
// ❌ 错误:不格式化
var code = classDecl.ToFullString();
// 输出:public class MyClass{public int Value{get;set;}}

解决方案: 使用 NormalizeWhitespace() 方法。

csharp
// ✅ 正确:格式化代码
var code = classDecl.NormalizeWhitespace().ToFullString();
// 输出:
// public class MyClass
// {
//     public int Value { get; set; }
// }

错误 3: 类型参数错误

问题: 创建泛型类型时类型参数错误。

csharp
// ❌ 错误:类型参数错误
var genericType = GenericName("List");  // 缺少类型参数

解决方案: 使用 TypeArgumentList 添加类型参数。

csharp
// ✅ 正确:添加类型参数
var genericType = GenericName(
    Identifier("List"),
    TypeArgumentList(
        SingletonSeparatedList<TypeSyntax>(
            PredefinedType(Token(SyntaxKind.IntKeyword)))));

🔗 相关文档

其他相关文档


📚 下一步

学习完本文档后,建议继续学习:

  1. 格式化和美化 - 学习如何格式化生成的代码
  2. 代码构建模式 - 学习常用的代码构建模式
  3. SyntaxFactory 高级 - 学习复杂结构的生成技术

最后更新: 2026-02-05
文档版本: 1.0

基于 MIT 许可发布