本文將告訴大家如何使用 ForAttributeWithMetadataName 方法用來提高 IIncrementalGenerator 增量 Source Generator 源代碼生成的開發效率以及提高源代碼生成器的運行效率
這是一個在 2022 的 6 月 15 才合入的新功能。原因是 Roslyn 團隊發現了大量的源代碼生成器和分析器項目都十分依賴 Attribute 的判斷,且許多團隊在實現的過程中都很難實現正確的增量方式,導致了許多多餘浪費的計算,影響性能
使用 ForAttributeWithMetadataName 的方法非常簡單,和 CreateSyntaxProvider 方法非常相似,只是添加了多了一個參數,這個參數就是所期望的 Attribute 名。假定正在編寫的源代碼生成器或分析器強依賴某個已知的特性,那通過 ForAttributeWithMetadataName 方法即可減少一些重複代碼的編寫和提升性能
代碼例子如下
var provider = context.SyntaxProvider.ForAttributeWithMetadataName("Lindexi.FooAttribute",
// 進一步判斷
(node, _) => node.IsKind(SyntaxKind.ClassDeclaration),
(syntaxContext, _) => syntaxContext.TargetSymbol.Name);
通過 ForAttributeWithMetadataName 方法,第一個參數傳入所期望的特性名,第二個參數和第三個參數將和 CreateSyntaxProvider 的第一個第二個參數相同,只是傳入的數據有所差別。此時的第二個參數的委託的 SyntaxNode 類型的對象就是已經標記了第一個參數的特性的成員,一般的進一步判斷的代碼都能簡單,除非是有業務需要的過濾條件
以上的代碼是過濾出所有標記了 Lindexi.FooAttribute
特性的類型
通過 ForAttributeWithMetadataName 方法可以由 Roslyn 底層儘量保持增量執行,也就是沒有變更的情況下不會執行,可以很大提升性能
可以試試將這些類型添加到源代碼生成裏面。詳細的代碼可以通過下文獲取所有的代碼,獲取的代碼裏面還包含了源代碼生成的單元測試,可以運行單元測試內容瞭解具體的生成器輸出以及進行調試
可以通過如下方式獲取本文的源代碼,先創建一個空文件夾,接着使用命令行 cd 命令進入此空文件夾,在命令行裏面輸入以下代碼,即可獲取到本文的代碼
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin ed3de9582fa11bb0c9b0fd02e34d2c4f89c21df0
以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換爲 github 的源。請在命令行繼續輸入以下代碼
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin ed3de9582fa11bb0c9b0fd02e34d2c4f89c21df0
獲取代碼之後,進入 JijalnairhelecheNakallchijall 文件夾
更多關於源代碼生成博客請參閱我的 博客導航