简体   繁体   English

C#如何在Roslyn中检测EvenHandler订阅

[英]C# How can i detect EvenHandler subscription in Roslyn

I'm writing a custom analyzer rule using Roslyn. 我正在使用Roslyn编写自定义分析器规则。

I want to find a method which is a handler for some event (via subscription). 我想找到一个方法来处理某些事件(通过订阅)。 Like this: 像这样:

public class Counter
{
    public event EventHandler ThresholdReached;
}

public class TestEvent
{
    public TestEvent()
    {
        Counter с = new Counter();
        с.ThresholdReached += OnThresholdReached;
    }

    private void OnThresholdReached(object sender, EventArgs e)
    {

    }
}

In my realization it looks: 在我的认识中,它看起来是:

    private static void HandleMethodDeclaration(SyntaxNodeAnalysisContext context)
    {
        MethodDeclarationSyntax methodDeclaration = (MethodDeclarationSyntax)context.Node;
        if (methodDeclaration.Identifier.IsMissing)
        {
            return;
        }

        IMethodSymbol methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodDeclaration);

    }

I don't know how to detect that OnThresholdReached is subscription of Event ThresholdReached . 我不知道如何检测OnThresholdReached是Event ThresholdReached的订阅。 If someone knows how to do it, please help=) 如果有人知道该怎么做,请帮助=)

In an analyzer, you cannot know only from looking at a MethodDeclarationSyntax , whether that method is converted to a delegate or not. 在分析器中,仅通过查看MethodDeclarationSyntax不能知道该方法是否转换为委托。 Because of that, you can not know (only from looking at a MethodDeclarationSyntax ) whether that delegate is passed to the add accessor of an event or not. 因此,您不能(仅通过查看MethodDeclarationSyntax )不知道该委托是否传递给事件的添加访问器。

First of all, remember that a Roslyn analyzer can only see usages in the current assembly (project). 首先,请记住Roslyn分析器只能查看当前程序集(项目)中的用法。 If your method is converted to a delegate in another assembly, there is no way for the analyzer to see this. 如果将您的方法转换为另一个程序集中的委托,则分析器将无法看到此结果。

Secondly, remember that 其次,请记住

с.ThresholdReached += OnThresholdReached;

may be expressed as 可以表示为

EventHandler handler = OnThresholdReached;
с.ThresholdReached += handler;

If you only want to detect the first case, you can look at AssignmentExpressionSyntax instances of kind SyntaxKind.AddAssignmentExpression , and analyze those. 如果只想检测第一种情况,则可以查看SyntaxKind.AddAssignmentExpression类型的AssignmentExpressionSyntax实例,并进行分析。

If you want to detect all cases where a method group is converted to a delegate, you need to look at all instances of type SimpleNameSyntax and analyze those as follows: 如果要检测将方法组转换为委托的所有情况,则需要查看所有类型为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
}

To find the source code for that method, see https://stackoverflow.com/a/45362532/1403794 . 要查找该方法的源代码,请参阅https://stackoverflow.com/a/45362532/1403794

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM