如何用Roslyn检测代码中的闭包

本文关键字:闭包 代码 检测 何用 Roslyn | 更新日期: 2023-09-27 17:49:29

我可以检测(使用roslyn), x引用在lambda体是封闭的外部变量x,而不是一些变量局部lambda本身?

var x = "foo";
var a = string[0];
a.Any(i => i == x);

如何用Roslyn检测代码中的闭包

是的。可以使用DataFlowAnalysis API

var tree = CSharpSyntaxTree.ParseText(
    @"
class C{
void M(){
    var x = ""foo"";
    var a = new string[0];
    var testing = a.Any(i => i == x);
}
} 
");
var Mscorlib = PortableExecutableReference.CreateFromAssembly(typeof(object).Assembly);
var compilation = CSharpCompilation.Create("MyCompilation",
    syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
var model = compilation.GetSemanticModel(tree);
var lambda = tree.GetRoot().DescendantNodes().OfType<LocalDeclarationStatementSyntax>().Last();
var dataFlowAnalysis = model.AnalyzeDataFlow(lambda);
var capturedVariables = dataFlowAnalysis.Captured;
foreach(var variable in capturedVariables)
{
    //Do something
}

https://github.com/mjsabby/RoslynClrHeapAllocationAnalyzer/blob/master/ClrHeapAllocationsAnalyzer/DisplayClassAllocationAnalyzer.cs#L58

(1)获取语义模型

(2)检查AnonymousMethodExpressionSyntax/SimpleLambdaExpressionSyntax/ParenthesizedLambdaExpressionSyntax

(3)将该节点传递给SemanticModel上的AnalyzeDataFlow扩展方法

(4)遍历。captured属性