Asteroid.CodeBuilder 1.0.2

dotnet add package Asteroid.CodeBuilder --version 1.0.2
                    
NuGet\Install-Package Asteroid.CodeBuilder -Version 1.0.2
                    
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.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Asteroid.CodeBuilder" Version="1.0.2" />
                    
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.2
                    
#r "nuget: Asteroid.CodeBuilder, 1.0.2"
                    
#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.2
                    
#: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.2
                    
Install as a Cake Addin
#tool nuget:?package=Asteroid.CodeBuilder&version=1.0.2
                    
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 net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.
  • 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 94 5/16/2026
1.0.1 111 5/15/2026
1.0.0 92 5/15/2026