В анализаторе вы не можете только узнать, взглянув на MethodDeclarationSyntax
, преобразован ли этот метод в делегат или нет. Из-за этого вы не можете знать (только глядя на MethodDeclarationSyntax
), передан ли этот делегат добавителю доступа события или нет.
Прежде всего, помните, что анализатор Roslyn может видеть только использования в текущей сборке (проекте). Если ваш метод преобразован в делегат в другой сборке, анализатор не сможет увидеть это.
Во-вторых, помните, что
с.ThresholdReached += OnThresholdReached;
может быть выражено как
EventHandler handler = OnThresholdReached;
с.ThresholdReached += handler;
Если вы хотите обнаружить только первый случай, вы можете посмотреть AssignmentExpressionSyntax
экземпляры вида SyntaxKind.AddAssignmentExpression
и проанализировать их.
Если вы хотите обнаружить все случаи, когда группа методов преобразуется в делегат, вам необходимо просмотреть все экземпляры типа 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.