Asteroid.CodeBuilder 1.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Asteroid.CodeBuilder --version 1.0.0
                    
NuGet\Install-Package Asteroid.CodeBuilder -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Asteroid.CodeBuilder" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Asteroid.CodeBuilder" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Asteroid.CodeBuilder" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Asteroid.CodeBuilder --version 1.0.0
                    
#r "nuget: Asteroid.CodeBuilder, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Asteroid.CodeBuilder@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Asteroid.CodeBuilder&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Asteroid.CodeBuilder&version=1.0.0
                    
Install as a Cake Tool

Asteroid.CodeBuilder

C# 代码生成引擎 — 通过 Fluent API 和 DAG 节点树以程序化方式生成 C# 源代码。

概述

Asteroid.CodeBuilder 是一个基于 .NET 的代码生成框架,核心设计理念是用结构化的代码节点树来建模 C# 语法,通过声明式的 API 链式调用生成源代码文本。适用于 Roslyn Source Generator、代码重构工具、元编程等场景。

架构

┌─────────────────────────────────────────────────────────────┐
│                      FileBuilder                           │
│          (文件级入口,持有 FileNode 根节点)                    │
└──────────────────────┬──────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│  CodeNode System (DAG 节点树)                                │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐    │
│  │ 声明节点  │ │ 表达式节点│ │ 语句节点  │ │ 组件节点     │    │
│  │ Class    │ │ Literal  │ │ If/Else  │ │ Modifier    │    │
│  │ Method   │ │ Invoke   │ │ For/Each │ │ Attribute   │    │
│  │ Property │ │ New      │ │ Try/Catch│ │ Param       │    │
│  │ Enum     │ │ Lambda   │ │ Switch   │ │ Constrain   │    │
│  │ Namespace│ │ Linq     │ │ Return   │ │ Comment/Doc │    │
│  └──────────┘ └──────────┘ └──────────┘ └─────────────┘    │
└──────────────────────┬──────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│  CodeNodeBuildContext (两阶段构建上下文)                      │
│  Phase1: Prepare → ShouldBuild 决策                          │
│  Phase2: Build → 输出代码文本                                 │
└──────────────────────┬──────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│  CodeTextBuilder (文本缓冲构建器)                              │
│  缩进管理 / RAII 作用域 / 行控制                              │
└─────────────────────────────────────────────────────────────┘

快速开始

1. 生成一个简单的类文件

using Asteroid.CodeBuilder;
using static Asteroid.CodeBuilder.Decl;
using static Asteroid.CodeBuilder.Exp;

var builder = FileBuilder.New("MyClass.cs");
builder.Root
    .FileNamespace("MyApp.Core")
    .Class("MyClass")
        .AsPublic()
        .DocSummary("核心业务类")
        .Method("DoWork")
            .AsPublic()
            .Param(typeof(int), "x")
            .With(Raw("Console.WriteLine(x)"));

string code = builder.ToCode(CancellationToken.None);
Console.WriteLine(code);

输出:

namespace MyApp.Core;

/// <summary>
/// 核心业务类
/// </summary>
public class MyClass
{
    public void DoWork(int x) => Console.WriteLine(x);
}

2. 生成枚举

var builder = FileBuilder.New("Permissions.cs");
builder.Root
    .FileNamespace("MyApp.Security")
    .Enum("Permissions")
        .AsPublic()
        .Attribute(Exp.Ns.System.Qa("Flags"));
builder.Root.Enum("Permissions")
    .Add("None").With(0)
    .Add("Read").With(1)
    .Add("Write").With(2)
    .Add("Admin").With(7);

3. 生成带 if/else 的方法体

using static Asteroid.CodeBuilder.St;
using static Asteroid.CodeBuilder.Exp;
using static Asteroid.CodeBuilder.Decl;

var method = Method("GetStatus")
    .AsPublic()
    .Param(typeof(int), "code");
    
method.Body.Add(
    If(GreaterThan(Id("code"), Literal(0)),
    [
        Return(String("positive"))
    ]));
method.Body.Add(
    ElseIf(LessThan(Id("code"), Literal(0)),
    [
        Return(String("negative"))
    ]));
method.Body.Add(
    Else([
        Return(String("zero"))
    ]));

4. 复杂属性生成

// 自动属性 + 默认值
Decl.AutoProperty(typeof(int), "Count").AsPublic().With(Literal(10));
// ⮕ public int Count { get; set; } = 10;

// 只读表达式体属性
Decl.GetterProperty(typeof(int), "Value").AsPublic().With(Literal(42));
// ⮕ public int Value => 42;

核心概念

节点基类 (CodeNodeBase)

所有代码节点继承自 CodeNodeBase,通过 ChildNodes 属性定义子节点,支持两阶段生命周期:

阶段 方法 用途
Prepare OnPrepare 初始化上下文
Prepare OnPrepareChild 准备子节点
Prepare OnPrepared 后处理
Prepare ShouldBuild 决定是否构建
Build OnBuildStart 构建前钩子
Build OnBuild 核心构建逻辑
Build OnBuildEnd 构建后钩子

核心规则:

  • 节点结构是有向无环图(DAG),节点之间无父子引用
  • 每个节点通过 ChildNodes 声明依赖关系
  • 两阶段确保最终输出内容按正确顺序组织

类型名系统

类型名可通过以下方式构建:

// 从 System.Type
var t1 = Exp.Type(typeof(List<int>));

// 从字符串
var t2 = Exp.Type("System.Collections.Generic.List<int>");

// 从 IdName(标识符)
var t3 = Exp.Id("myVar");

// 泛型类型
var t4 = Exp.Generic("List", [Exp.Type(typeof(int))]);

// QaName (Qualified Name) — 带命名空间的类型名
var t5 = Exp.Qa("System.Collections.Generic", "List");

// 利用预定义命名空间快捷方式
var t6 = Exp.Ns.System.Qa("StringBuilder");
// ⮕ System.Text.StringBuilder

// 隐式转换
TypeName tn = "MyClass";
ExpNode en = "someVariable";   // 隐式转为 Raw 表达式

预定义的命名空间快捷方式(Exp.Ns):

属性
Exp.Ns.System System
Exp.Ns.SystemCollectionsGeneric System.Collections.Generic
Exp.Ns.SystemIO System.IO
Exp.Ns.SystemLinq System.Linq
Exp.Ns.SystemNetHttp System.Net.Http
Exp.Ns.SystemThreading System.Threading
Exp.Ns.SystemThreadingTasks System.Threading.Tasks
Exp.Ns.SystemDiagnosticsCodeAnalysis System.Diagnostics.CodeAnalysis

文件节点 (FileNode)

文件节点支持:

var builder = FileBuilder.New("Service.cs", "Copyright 2024");
builder.Root
    .FileNamespace("App")                    // 文件作用域命名空间
    .Using(Exp.Ns.SystemLinq)                // using 指令
    .UsingStatic(Exp.Ns.System.Qa("Console"))// using static 指令
    .NullableEnable()                        // #nullable enable
    .GlobalUsing(Exp.Ns.SystemCollectionsGeneric) // global using
    .WarningDisable_RequireNewFlag()         // #pragma warning disable CS0108
    .Class("Service").AsPublic();

API 参考

声明节点工厂 (Decl)

所有声明类型:

方法 生成代码
Decl.Class("MyClass") class MyClass { ... }
Decl.Record("MyRecord") record MyRecord { ... }
Decl.Struct("MyStruct") struct MyStruct { ... }
Decl.Interface("IMyInterface") interface IMyInterface { ... }
Decl.Enum("MyEnum") enum MyEnum { ... }
Decl.Delegate(type, name) delegate type Name(...);
Decl.Event(type, name) event type name;
Decl.Indexer(type) type this[...] { get; set; }

方法变体:

方法 生成代码
Decl.Method(type, "DoWork") type DoWork(...) { ... }
Decl.Method("DoWork") void DoWork(...) { ... }
Decl.Constructor("MyClass") MyClass(...) { ... }
Decl.Destructor("MyClass") ~MyClass() { ... }
Decl.Operator(type, "op") static type operator op(...) { ... }
Decl.ImplicitConverter(type, param) static implicit operator type(param) { ... }
Decl.ExplicitConverter(type, param) static explicit operator type(param) { ... }

属性变体:

方法 生成代码
Decl.Property(type, "Name") type Name { get; set; }
Decl.AutoProperty(type, "Name") type Name { get; set; } = default;
Decl.GetterProperty(type, "Name") type Name => expr;
Decl.GetterAutoProperty(type, "Name") type Name { get; } = default;

特殊方法:

方法 生成代码
Decl.Method_Deconstruct(params) void Deconstruct(...) { ... }
Decl.Method_Override_Equals(type) public override bool Equals(object obj)
Decl.Method_Override_GetHashCode(values) public override int GetHashCode()
Decl.Method_Override_ToString(exp) public override string ToString()

链式修饰符(扩展方法):

方法 作用
.AsPublic() / .AsPrivate() / .AsInternal() 访问修饰符
.AsProtected() / .AsProtectedInternal() / .AsPrivateProtected() / .AsFile() 访问修饰符
.AsStatic() / .AsPartial() / .AsOverride() 类型修饰符
.AsAbstract() / .AsVirtual() / .AsSealed() 行为修饰符
.AsReadonly() / .AsAsync() / .AsNew() 其他修饰符
.AsUnsafe() / .AsExtern() / .AsImplicit() / .AsExplicit() 特殊修饰符

表达式工厂 (Exp)

字面量

方法 生成代码
Exp.Literal(42) 42
Exp.Literal(3.14f) 3.14f
Exp.Literal(true) true
Exp.Literal('x') 'x'
Exp.String("hello") "hello"
Exp.VerbatimString("a\\b") @"a\\b"
Exp.RawString("multi\\nline") """multi\\nline"""
Exp.Null null
Exp.Default default

标识符与访问

方法 生成代码
Exp.Id("x") x
Exp.Id("class") @class(关键字自动转义)
Exp.Raw("x + y") x + y(原始文本)
Exp.Empty (空,不输出)
obj.Acc(member) obj.member
obj.NAcc(member) obj?.member
obj.PAcc(member) obj->member

调用与索引

方法 生成代码
Exp.Invoke(f) f()
Exp.Invoke(f, [a, b]) f(a, b)
obj.Invoke(m, args) obj.m(args)
obj.NInvoke(m, args) obj?.m(args)
obj.PInvoke(m, args) obj->m(args)
Exp.Index(arr, 0) arr[0]
Exp.NIndex(arr, 0) arr?[0]

一元运算符

方法 生成代码
Exp.Positive(x) +x
Exp.Negative(x) -x
Exp.Not(flag) !flag
Exp.Bit_Not(x) ~x
Exp.PreInc(x) ++x
Exp.PostInc(x) x++
Exp.PreDec(x) --x
Exp.PostDec(x) x--
Exp.AddressOf(x) &x
Exp.PointerDeref(x) *x

二元运算符

方法 生成代码
Exp.Plus(a, b) a + b
Exp.Minus(a, b) a - b
Exp.Multiply(a, b) a * b
Exp.Divide(a, b) a / b
Exp.Modulo(a, b) a % b
Exp.Equal(a, b) a == b
Exp.NotEqual(a, b) a != b
Exp.LessThan(a, b) a < b
Exp.GreaterThan(a, b) a > b
Exp.LessThanOrEqual(a, b) a <= b
Exp.GreaterThanOrEqual(a, b) a >= b
Exp.And(a, b) a && b
Exp.Or(a, b) a \|\| b
Exp.BitAnd(a, b) a & b
Exp.BitOr(a, b) a \| b
Exp.BitXor(a, b) a ^ b
Exp.LShift(a, b) a << b
Exp.RShift(a, b) a >> b
Exp.URShift(a, b) a >>> b
Exp.NC(a, b) a ?? b
Exp.NF(exp) exp!(null 包容)
Exp.Sum([a, b, c]) a + b + c(链式求和)
Exp.Product([a, b, c]) a * b * c(链式求积)

赋值运算符

方法 生成代码
Exp.Assign(a, b) a = b
Exp.PlusAssign(a, b) a += b
Exp.MinusAssign(a, b) a -= b
Exp.MultiplyAssign(a, b) a *= b
Exp.DivideAssign(a, b) a /= b
Exp.ModuloAssign(a, b) a %= b
Exp.AndAssign(a, b) a &= b
Exp.OrAssign(a, b) a \|= b
Exp.XorAssign(a, b) a ^= b
Exp.LShiftAssign(a, b) a <<= b
Exp.RShiftAssign(a, b) a >>= b
Exp.URShiftAssign(a, b) a >>>= b
Exp.NCAssign(a, b) a ??= b

类型操作

方法 生成代码
Exp.Cast(x, type) (type)x
Exp.As(x, type) x as type
Exp.TypeOf(type) typeof(type)
Exp.NameOf(x) nameof(x)
Exp.SizeOf(type) sizeof(type)
Exp.DefaultOf(type) default(type)

三目与括号

方法 生成代码
Exp.Ternary(cond, a, b) cond ? a : b
Exp.P(exp) (exp)
Exp.Range(a, b) a..b
Exp.Spread(x) ..x
Exp.FromEnd(x) ^x
Exp.Await(task) await task

Checked / Unchecked

方法 生成代码
Exp.Checked(exp) checked(exp)
Exp.Unchecked(exp) unchecked(exp)

变量声明表达式

方法 生成代码
Exp.DeclVar(type, name) type name
Exp.DeclVar("x") var x
Exp.DeclDeconstructVar(["x","y"]) var (x, y)

Lambda

方法 生成代码
Exp.Lambda(param, body) param => body
Exp.Lambda("x", x.Acc("Name")) x => x.Name
Lambda(...).AsStatic() static x => ...

对象创建

方法 生成代码
Exp.New(type) new type()
Exp.NewAnonymous() new { ... }
Exp.NewArray(type, rank) new type[...] { ... }
Exp.NewAnonymousArray() new[] { ... }
Exp.StackAlloc(type, len) stackalloc type[len]
Exp.With(source, inits) source with { ... }
Exp.KVInit(key, value) { key, value }

变量声明与初始化

var decl = Exp.DeclVar(typeof(int), "count");
// ⮕ int count

var assign = decl.Assign(Literal(42));
// ⮕ int count = 42

Throw 表达式

方法 生成代码
Exp.Throw(ex) throw ex;
Exp.Throw_NotSupport() throw new NotSupportedException();
Exp.Throw_NotImplemented() throw new NotImplementedException();

模式匹配

方法 生成代码
Exp.Is(exp, pattern) exp is pattern
Exp.Is(exp, type, name) exp is type name
Exp.IsNotNull(exp, name) exp is { } name
Exp.IsNot(exp, pattern) exp is not pattern
Exp.PNot(exp) not exp
Exp.POr(a, b) a or b
Exp.PAnd(a, b) a and b
Exp.When(pattern, cond) pattern when cond
Exp.PropertyPattern(matches) { Prop: pattern }
Exp.Switch(val, arms) val switch { arms }
Exp.SwitchArm(pattern, exp) pattern => exp

集合与元组

方法 生成代码
Exp.Collection([a, b]) [a, b]
Exp.Tuple([a, b]) (a, b)
Exp.Init([a, b]) { a, b }

参数与引用

方法 生成代码
Exp.Param(type, name) type name
Exp.Arg(exp) exp
Exp.NamedArg("x", exp) x: exp
Exp.Arg_Ref(exp) ref exp
Param(...).WithRef() ref type name
Param(...).WithOut() out type name
Param(...).WithIn() in type name
Param(...).WithThis() this type name

LINQ 查询表达式

Exp.Linq()
    .From("p", Exp.Id("people"))
    .Where(Exp.GreaterThan(Exp.Id("p").Acc("Age"), Literal(18)))
    .Select(Exp.Id("p").Acc("Name"));
// ⮕ from p in people
//    where p.Age > 18
//    select p.Name
方法 生成代码
Exp.Linq() LINQ 表达式组容器
Exp.LinqFrom(var, src) from var in src
Exp.LinqLet(var, val) let var = val
Exp.LinqWhere(cond) where cond
Exp.LinqSelect(result) select result
Exp.LinqGroupBy(var, key, into) group var by key into g
Exp.LinqOrderBy(val) orderby val ascending
Exp.LinqJoin(...) join ... in ... on ... equals ...

语句工厂 (St)

基本语句

方法 生成代码
St.Line(exp) exp;
St.Comment("text") // text
St.EmptyLine (空行)
St.Block([...]) { ... }

条件语句

方法 生成代码
St.If(cond, [stmts]) if (cond) { ... }
St.ElseIf(cond, [stmts]) else if (cond) { ... }
St.Else([stmts]) else { ... }

循环语句

方法 生成代码
St.While(cond) while (cond) { ... }
St.For(init, cond, step) for (init; cond; step) { ... }
St.ForN(var, max) for (int i = 0; i < max; i++) { ... }
St.Foreach(type, name, coll) foreach (type name in coll) { ... }
St.Foreach(name, coll) foreach (var name in coll) { ... }
St.DoWhile(cond) do { ... } while (cond);

Switch 语句

方法 生成代码
St.Switch(cond) switch (cond) { ... }
Switch.Case(exp, [stmts]) case exp: ...
Switch.DefaultCase([stmts]) default: ...

Try/Catch 语句

方法 生成代码
St.Try([stmts]) try { ... }
St.Catch([stmts]) catch { ... }
St.Catch(varDecl, when, [stmts]) catch (varDecl) when (cond) { ... }
St.Finally([stmts]) finally { ... }

其他语句

方法 生成代码
St.Section([stmts]) 隐式区段
St.Region("name", [stmts]) #region name ... #endregion
St.Using(exp, [stmts]) using (exp) { ... }
St.UsingVar(decl, exp) using var = exp;
St.Fixed(decl, exp, [stmts]) fixed (decl = exp) { ... }
St.Unsafe([stmts]) unsafe { ... }
St.Checked([stmts]) checked { ... }

组件节点

修饰符

所有声明节点可通过 .AsXxx() 链式设置修饰符。自动处理修饰符冲突(如 AsPublic() 会移除其他访问修饰符)。

支持的修饰符:

  • 访问级别:public / private / internal / protected / protected internal / private protected / file
  • 类型:static / partial / abstract / virtual / override / sealed
  • 成员:readonly / const / volatile / async / new / unsafe / extern
  • 属性:required / ref

特性 (Attribute)

cls.Attribute(Exp.Ns.System.Qa("Serializable"));
// ⮕ [Serializable]

cls.Attribute(Exp.Ns.System.Qa("Obsolete"));
// ⮕ [Obsolete]

// 带参数的特性
attr.Arg(Exp.String("Use NewMethod instead"));
// ⮕ [Obsolete("Use NewMethod instead")]

文档注释

Decl.Class("MyClass").AsPublic()
    .DocSummary("A class that does things")
    .Doc("Use <see cref=\"DoWork\"/> to start");

// ⮕ /// <summary>
//    /// A class that does things
//    /// </summary>
//    /// Use <see cref="DoWork"/> to start

Doc 帮助类:

方法 输出
Doc.Para("text") <para>text</para>
Doc.SeeCref("MyClass") <see cref="MyClass"/>
Doc.SeeHref("link", "text") <see href="link">text</see>
Doc.SeeLangword("true") <see langword="true"/>

泛型约束

cls.Param(typeof(T), "T");
cls.Constrain("T").With(Exp.Id("class", false));
// ⮕ where T : class

继承列表

cls.Inherit("IMyInterface");
cls.Inherit("BaseClass");
// ⮕ class MyClass : BaseClass, IMyInterface

节区 (Section)

var cls = Decl.Class("MyClass").AsPublic();
var ctorSection = cls.Section("#region Constructors");
ctorSection.Constructor("MyClass").AsPublic();

文件预处理器指令

方法 生成代码
Preprocessor.Nullable_Enable() #nullable enable
Preprocessor.Nullable_Disable() #nullable disable
Preprocessor.Nullable_Restore() #nullable restore
Preprocessor.Pragma_WarningDisable("CS0108") #pragma warning disable CS0108
Preprocessor.Define("DEBUG") #define DEBUG
Preprocessor.Undefine("DEBUG") #undef DEBUG
Preprocessor.If(cond) #if cond
Preprocessor.Elif(cond) #elif cond
Preprocessor.Else() #else
Preprocessor.EndIf() #endif

CodeTextBuilder

底层文本构建器,供高级定制使用:

成员 用途
Append(text) 追加文本
AppendLine(text) 追加文本并换行
AppendNodes(nodes) 追加子节点列表
IndentLevel 获取/设置缩进级别
Indenter 缩进字符串(默认 \t
NewLine 换行符(默认 \n
NewIndentScope() RAII 缩进作用域
NewSetIndentScope(level) RAII 固定缩进作用域
NewParenthesesScope(...) RAII 括号作用域
NewCurlyBracesScope(...) RAII 花括号作用域
NewBracketsScope(...) RAII 方括号作用域
StartLine() / EndLine() 行控制

ImplicitUsings

启用 Option.EnableImplicitUsings 后,自动注入以下命名空间:

  • System
  • System.IO
  • System.Collections.Generic
  • System.Linq
  • System.Net.Http
  • System.Threading
  • System.Threading.Tasks

完整示例

生成一个完整的 .cs 文件

using Asteroid.CodeBuilder;
using static Asteroid.CodeBuilder.Decl;
using static Asteroid.CodeBuilder.Exp;
using static Asteroid.CodeBuilder.St;

public string GenerateServiceFile()
{
    var builder = FileBuilder.New("UserService.cs", "Auto-generated");
    var root = builder.Root;

    // 文件头
    root.FileNamespace("MyApp.Services");
    root.Using(Exp.Ns.SystemLinq);
    root.Class("UserService").AsPublic()
        .DocSummary("用户服务")

        // 字段
        .Field(typeof(List<User>), "_users")
            .AsPrivate()
            .With(New(Exp.Generic("List", [Exp.Type(typeof(User))])))

        // 构造函数
        .Constructor("UserService")
            .AsPublic()

        // 属性
        .AutoProperty(typeof(int), "Count")
            .AsPublic()

        // 方法
        .Method("GetUser")
            .AsPublic()
            .Param(typeof(int), "id")
            .With(Ternary(Equal(Id("id"), Literal(0)),
                Exp.Null,
                Exp.Invoke(Exp.Id("_users"), "FirstOrDefault", [Exp.Lambda("u", u =>
                    Exp.Equal(u.Acc("Id"), Id("id")))])));

    return builder.ToCode(CancellationToken.None);
}

使用方法体填充复杂逻辑

var method = Decl.Method("ProcessData")
    .AsPublic()
    .Param(typeof(int), "value");

method.Body.Add(If(GreaterThan(Id("value"), Literal(100)),
[
    St.Line(Exp.Invoke("Log", Exp.String("Large value"))),
    Return(Id("value"))
]));

method.Body.Add(
    St.Try([
        St.Line(Invoke(Id("Process"), Id("value"))),
    ]));

method.Body.Add(
    St.Catch(Exp.DeclVar(typeof(Exception), "ex"), [
        St.Line(Invoke("LogError", Id("ex"))),
    ]));

method.Body.Add(
    St.Finally([
        St.Line(Invoke(Id("Cleanup"))),
    ]));

安装

通过 NuGet 安装:

dotnet add package Asteroid.CodeBuilder

或直接引用项目:

<ProjectReference Include="..\CodeBuilder\Asteroid.CodeBuilder.csproj" />
Exp.Lambda(p, e) p => e
Exp.Plus(a, b) a + b
Exp.Ternary(c, t, f) c ? t : f
Exp.Is(e, p) e is p
Exp.Switch(v, arms) v switch { arms }
Exp.Throw(e) throw e

语句工厂 (St)

方法 生成代码
St.Line(exp) exp;
St.Block(stmts) { stmts }
St.If(cond, stmts) if (cond) { stmts }
St.ElseIf(cond, stmts) else if (cond) { stmts }
St.Else(stmts) else { stmts }
St.While(cond, stmts) while (cond) { stmts }
St.For(init, cond, step) for (init; cond; step) { ... }
St.Foreach(type, n, col) foreach (type n in col) { ... }
St.Try(stmts) try { stmts }
St.Catch(var, when, stmts) catch (var) when (when) { stmts }
St.Finally(stmts) finally { stmts }
St.Return(exp) return exp;
St.Switch(cond, cases) switch (cond) { cases }

项目依赖

  • .NET 10
  • 无第三方依赖

在 Source Generator 中使用

[Generator]
public class MyGenerator : IIncrementalGenerator
{
    public void Initialize(IncrementalGeneratorInitializationContext ctx)
    {
        ctx.RegisterPostInitializationOutput(static context =>
        {
            var builder = FileBuilder.New("GeneratedClass.cs");
            builder.Root
                .FileNamespace("MyNamespace")
                .Class("GeneratedClass")
                    .AsPublic()
                    .Method("Hello")
                        .AsPublic()
                        .AsStatic()
                        .With(Raw("Console.WriteLine(\"Hello from source generator!\")"));

            context.AddSource("GeneratedClass.g.cs", builder.ToCode(CancellationToken.None));
        });
    }
}

许可证

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 93 5/16/2026
1.0.1 110 5/15/2026
1.0.0 91 5/15/2026