2015-05-18 8 views
9

Kann ich (mit Roslyn) erkennen, dass x Bezug in der Lambda-Körper ist Schließung über äußere Variable x, nicht eine Variable lokal zu Lambda selbst?Wie erkennt man Verschlüsse im Code mit Roslyn?

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

'X' wäre ein Feld von einigen Verschluss Klasse sein, wenn es ein Frei/erfasst variabel ist. – leppie

+3

Werfen Sie einen Blick auf [RoslynClrHeapAllocationAnalyzer] (https://github.com/mjsabby/RoslynClrHeapAllocationAnalyzer). Es analysiert Speicherzuordnungen sowie Schließungen. –

+1

@YuvalItzchakov danke für den Link, es ist jetzt klar, dass ich überprüfen müssen "Captured" -Eigenschaft von "DataFlowAnalysis" -Objekt, das ich von 'SemanticModel bekommen kann. – Seldon

Antwort

4

Yup. Sie können die API DataFlowAnalysis verwenden.

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 
} 
Verwandte Themen