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)))));🔗 相关文档
- 返回索引
- SyntaxFactory 高级 - 学习复杂结构的生成技术
- 代码构建模式 - 学习常用的代码构建模式
- 格式化和美化 - 学习如何格式化生成的代码
- 最佳实践 - 掌握代码生成的最佳实践
其他相关文档
📚 下一步
学习完本文档后,建议继续学习:
- 格式化和美化 - 学习如何格式化生成的代码
- 代码构建模式 - 学习常用的代码构建模式
- SyntaxFactory 高级 - 学习复杂结构的生成技术
最后更新: 2026-02-05
文档版本: 1.0