[英]Is an ISymbol from different compilations considered equal in an IIncrementalGenerator
使用IIncrementalGenerator
而不是ISourceGenerator
的好處之一是管道的不同階段可以識別當前迭代的結果與先前迭代的結果相同並使用緩存的結果。
為了讓它工作,大概任何IncrementalValueProvider
或IncrementalValuesProvider
的類型參數都需要是可等值的,(與默認的可等值引用相反)這大概就是為什么你會看到很多使用record
實現的源生成器
這就引出了一個問題,如果IncrementalValueProvider
等式ISymbol
包含表示相同語義 object 的 ISymbol,那么在管道的不同迭代期間,出於緩存比較的目的,它們是否會被視為相等?
放棄引用ISymbol
並從中提取我需要的數據(名稱、名稱空間、成員等)會更好嗎?
我已經深入研究了 Symbol 實現的 Equals 函數,目前還不清楚,base class Symbol.Equals()
確實使用了引用比較,但這似乎在大多數(可能是所有)派生類中被覆蓋了。 並且對這些覆蓋進行抽查似乎它們正在嘗試具有值相等性,但是同樣,有很多需要檢查的地方,即使最終確實使用了引用相等性檢查,符號引用也可能是在運行之間緩存,甚至引用等於檢查也將為真。
放棄引用ISymbol
並從中提取我需要的數據(名稱、名稱空間、成員等)會更好嗎?
不要在管道中包含符號。 不僅它們比較不相等,而且它們還在 memory 中進行根編譯,並可能導致 memory 的高使用率。
下面的小片段顯示了符號如何比較不相等,即使它們來自完全相同的語法樹:
var trees = new[] { SyntaxFactory.ParseSyntaxTree("public class C { }") };
var comp1 = CSharpCompilation.Create(null, trees);
var s1 = comp1.GetTypeByMetadataName("C");
var comp2 = CSharpCompilation.Create(null, trees);
var s2 = comp2.GetTypeByMetadataName("C");
Console.WriteLine(s1.Equals(s2, SymbolEqualityComparer.Default));
但即使您提供自己的相等性比較器,root 編譯仍然是一個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.