[英]C# How can i detect EvenHandler subscription in Roslyn
我正在使用Roslyn编写自定义分析器规则。
我想找到一个方法来处理某些事件(通过订阅)。 像这样:
public class Counter
{
public event EventHandler ThresholdReached;
}
public class TestEvent
{
public TestEvent()
{
Counter с = new Counter();
с.ThresholdReached += OnThresholdReached;
}
private void OnThresholdReached(object sender, EventArgs e)
{
}
}
在我的认识中,它看起来是:
private static void HandleMethodDeclaration(SyntaxNodeAnalysisContext context)
{
MethodDeclarationSyntax methodDeclaration = (MethodDeclarationSyntax)context.Node;
if (methodDeclaration.Identifier.IsMissing)
{
return;
}
IMethodSymbol methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodDeclaration);
}
我不知道如何检测OnThresholdReached是Event ThresholdReached的订阅。 如果有人知道该怎么做,请帮助=)
在分析器中,仅通过查看MethodDeclarationSyntax
不能知道该方法是否转换为委托。 因此,您不能(仅通过查看MethodDeclarationSyntax
)不知道该委托是否传递给事件的添加访问器。
首先,请记住Roslyn分析器只能查看当前程序集(项目)中的用法。 如果将您的方法转换为另一个程序集中的委托,则分析器将无法看到此结果。
其次,请记住
с.ThresholdReached += OnThresholdReached;
可以表示为
EventHandler handler = OnThresholdReached;
с.ThresholdReached += handler;
如果只想检测第一种情况,则可以查看SyntaxKind.AddAssignmentExpression
类型的AssignmentExpressionSyntax
实例,并进行分析。
如果要检测将方法组转换为委托的所有情况,则需要查看所有类型为SimpleNameSyntax
实例,并进行如下分析:
void Analyze(SyntaxNodeAnalysisContext context)
{
var node = context.Node as SimpleNameSyntax;
// we're only interested in delegates
var type = context.SemanticModel.GetTypeInfo(node, context.CancellationToken).ConvertedType;
if (type == null || type.TypeKind != TypeKind.Delegate)
{
return;
}
// we're only interested in methods from the current assembly
var symbol = context.SemanticModel.GetSymbolInfo(node, context.CancellationToken).Symbol;
if (symbol == null ||
symbol.Kind != SymbolKind.Method ||
!symbol.ContainingAssembly.Equals(context.SemanticModel.Compilation.Assembly))
{
return;
}
// now you know symbol is a method in the same assembly, that is converted to a delegate
}
要查找该方法的源代码,请参阅https://stackoverflow.com/a/45362532/1403794 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.