Skip to content

donetsoftwork/Hand.Generators

Repository files navigation

SourceGenerator填坑

  • 节约重复代码编写
  • 使得代码更简洁易读
  • 代替反射提高性能,AOT友好

一、代码的三种形态

1. SourceText

  • 源码文本

2. SyntaxTree

  • 语法树

3. ISymbol

  • 符号,相当于反射成员信息

二、SyntaxTree可以转化为SourceText

var userType = SyntaxFactory.ClassDeclaration("User")
    .AddMembers(
        SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName("string"), "Name")
        .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
        .AddAccessorListAccessors(
            SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
            SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
        ));
string sourceText = userType.ToFullString();

三、SourceText可以转化为SyntaxTree

string sourceText = @"
class User
{
    public string Name { get; set; }
}";
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceText);

四、SourceText可以转化为ISymbol

  • 可以通过编译转化为ISymbol
  • 但是ISymbol是不能转化为源码
  • ISymbol用于反射类型信息
string sourceText = @"
class User
{
    public string Name { get; set; }
}";
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceText);
var compilation = CSharpCompilation.Create("Tests", [syntaxTree]);
INamedTypeSymbol? userSymbol = compilation.GetTypeByMetadataName("User");

五、SourceGenerator默认把源码转化为SyntaxTree和ISymbol

给代码增加注释

1. 普通注释

var userType = SyntaxFactory.ClassDeclaration("User")
    .WithLeadingTrivia(SyntaxFactory.TriviaList(
        SyntaxFactory.Comment("// <auto-generated/>")
    )
);

1.1 效果如下

// <auto-generated/>
class User
{
}

About

代码生成器

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages