日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

抽丝剥茧!Source Generators原理讲解

發布時間:2023/12/4 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 抽丝剥茧!Source Generators原理讲解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

前段時間,我們已經用Source Generators實現了好多功能,比如AutoMapper、API最佳實踐。

你看完那些實現代碼,是不是還有點云里霧里!

Source Generators到底是怎么做到的?

基礎知識

Source Generators是編譯過程的一部分,它以編譯樹作為輸入,通過分析代碼,動態生成文件并把它們加入到編譯過程中:

需要注意的是,你只能添加一些東西到代碼,但不能改變現有的代碼。

為了使用Source Generators,你必須創建.Net Standard項目,并引用nuget包Microsoft.CodeAnalysis.CSharp 3.8.0或以上版本。

基本的實現代碼如下,你必須實現ISourceGenerator接口,并且用GeneratorAttribute標注:

[Generator] public?class?DemoSourceGenerator?:?ISourceGenerator {public?void?Execute(GeneratorExecutionContext?context){throw?new?NotImplementedException();}public?void?Initialize(GeneratorInitializationContext?context){throw?new?NotImplementedException();} }

生成器執行上下文

主要生成過程通過Execute方法執行。

Execute傳遞一個GeneratorExecutionContext實例,下列是實例常用的屬性和方法:

  • AdditionalFiles 獲取當前編譯項目文件中的所有AdditionalFiles標簽

  • Compilation 編譯上下文,最重要的對象

  • AddSource 向編譯器加入代碼,最重要的方法

語法樹

通過GeneratorExecutionContext.Compilation我們可以獲得編譯上下文,有了這個對象,你就可以訪問當前編譯項目的整個語法樹(SyntaxTree)。

那什么是語法樹呢?

首先,安裝.NET Compiler Platform SDK。

然后,在VS中打開“視圖”->“其他窗口”->“Syntax Visualizer”。

可以看到,語法樹是一個樹形結構,和每一行代碼一一對應

語法樹包含三種類型的項——node、token和trivia。

比如public class Class1 { }整體是ClassDeclaration node,下級的Class1則是ClassKeyword token, 而緊跟的空格則是Whitespace trivia。

因此,只要我們遍歷語法樹,即可拿到編譯中的任何代碼。

Demo

現在把上面的綜合起來,我們就可以開發Source Generators功能了:

public?void?Execute(GeneratorExecutionContext?context) {//獲取第一個附加文件內容,用作代碼模板var?template?=?context.AdditionalFiles.First().GetText().ToString();//獲取第一個類名var?className?=?context.Compilation.SyntaxTrees.SelectMany(p?=>?p.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>()).First().Identifier.Text;//?替換文本生成代碼//?你也可以使用模板引擎或者StringBuilder拼接出代碼var?source?=?template.Replace("{Class}",?className);//?向編譯過程添加代碼文件context.AddSource("Demo",?SourceText.From(source,?Encoding.UTF8)); }

在待編譯的項目中添加一個附加文件

<ItemGroup><AdditionalFiles?Include="template.txt"??/> </ItemGroup>

template.txt的文件內容如下:

using?System;namespace?ClassLibrary1 {public?static?class?Demo{public?static?void?SayHello(){Console.WriteLine("Hello {Class}!");}} }

編譯后,可以看到生成如下代碼:

結論

希望我已經描述清楚了使用Source Generators的整個過程。

期待你用它開發出更多更好的功能!

如果你覺得這篇文章對你有所啟發,請關注我的個人公眾號”My IO“,記住我!

總結

以上是生活随笔為你收集整理的抽丝剥茧!Source Generators原理讲解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。