c# - C#如何在 Roslyn 中检测 EvenHandler 订阅
问题描述
我正在使用 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的订阅。如果有人知道怎么做,请帮助=)
解决方案
在分析器中,您不能仅通过查看 a 来MethodDeclarationSyntax
知道该方法是否转换为委托。因此,您无法知道(仅通过查看 a MethodDeclarationSyntax
)该委托是否已传递给事件的 add 访问器。
首先,请记住 Roslyn 分析器只能查看当前程序集(项目)中的用法。如果您的方法在另一个程序集中转换为委托,则分析器无法看到这一点。
其次,记住
с.ThresholdReached += OnThresholdReached;
可以表示为
EventHandler handler = OnThresholdReached;
с.ThresholdReached += handler;
如果您只想检测第一种情况,您可以查看AssignmentExpressionSyntax
kind 的实例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。
推荐阅读
- linq - 我有 Linq 的问题。哪里没找到
- r - 是否使用 r 中的插入符号训练了 glmnet 模型中原始尺度的变量系数
- javascript - 如何根据d3中的第三列给出颜色?
- reactjs - 在组件更新时在 Redux 中保存 React 组件滚动位置
- python - 广播加入 pyspark
- mysql - 根据年份列表示各个城市的sql数据
- algorithm - 检查 N^2 个元素是否可以转换为 N*N 对称矩阵的程序?
- c# - 如何在 C#(MonoDroid) 中将 EditText 长度限制为 6 个整数和 3 个小数位?
- angular - 我有一个“过滤器”功能,它假设根据名称过滤来自 Firestore 的数据。我能够从 firestore 获取全部数据
- javascript - 如何在文本区域内添加表情符号或图像图标?