Roslyn Analyzer - 查找接口方法调用的当前具体实现
Roslyn Analyzer - Finding the current concrete implementation of interface's method call
我正在尝试编写一个 Roslyn 分析器来检测来自接口特定实现的方法调用,但我在检测实现类型方面遇到了问题。
当我使用一个类型化的变量作为具体实现时,它正确地识别了方法,但当我使用一个类型化的变量作为接口时,它却不正确。主要是想弄清楚如何使用 Roslyn 代码分析 Apis
获取接口的底层实现类型
这是要分析的示例代码。它正确检测到第二个 Operate
方法调用但不是第一个,即使两者都使用 Operable
中的具体实现
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
IOperable ioperable = new Operable();
ioperable.Operate();
Operable operable = new Operable();
operable.Operate();
}
}
public interface IOperable
{
void Operate();
}
public class Operable : IOperable
{
public void Operate()
{
}
}
}
这是我当前的来源:
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeInvocation, SyntaxKind.InvocationExpression);
}
private static void AnalyzeInvocation(SyntaxNodeAnalysisContext context)
{
var invocation = (InvocationExpressionSyntax)context.Node;
var memberAccess = invocation.Expression as MemberAccessExpressionSyntax;
if (memberAccess == null || !memberAccess.IsKind(SyntaxKind.SimpleMemberAccessExpression))
{
return;
}
var ident = memberAccess.Name.Identifier;
if (ident.ToString().ToLower() != "operate")
{
return;
}
var calledFromType = context.SemanticModel.GetTypeInfo(memberAccess.Expression).Type;
if (calledFromType.MetadataName != "Operable")
{
return;
}
context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation()));
}
我会让你失望,但 Roslyn 是一个静态分析器,默认情况下它不可能检索类型、调用等的动态信息。
为了实现这一目标,您需要在 roslyn 下实施自定义动态分析,该分析将调查所有变量赋值、参数传递等,以确定有关对象(类型、方法等)的所有信息,它可以当前时间在代码中。
在下面的例子中要清楚:
public interface IOperable
{
void Operate();
}
public class Operable : IOperable
{
...
}
public class OperableOther : IOperable
{
...
}
...
IOperable ioperable = new Operable();
ioperable.Operate(); // at this time will invoke Operable.Operate();
ioperable = new OperableOther();
ioperable.Operate(); // at this time will OperableOther.Operate();
Roslyn 可以检索关于变量 ioperable
的编译时信息,它是一个 IOperable
,但不能给出它将 Operable
从第一次分配和 OperableOther
从第二。但是如果你会累积所有变量修改等,你可以自己做。
我正在尝试编写一个 Roslyn 分析器来检测来自接口特定实现的方法调用,但我在检测实现类型方面遇到了问题。
当我使用一个类型化的变量作为具体实现时,它正确地识别了方法,但当我使用一个类型化的变量作为接口时,它却不正确。主要是想弄清楚如何使用 Roslyn 代码分析 Apis
获取接口的底层实现类型这是要分析的示例代码。它正确检测到第二个 Operate
方法调用但不是第一个,即使两者都使用 Operable
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
IOperable ioperable = new Operable();
ioperable.Operate();
Operable operable = new Operable();
operable.Operate();
}
}
public interface IOperable
{
void Operate();
}
public class Operable : IOperable
{
public void Operate()
{
}
}
}
这是我当前的来源:
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeInvocation, SyntaxKind.InvocationExpression);
}
private static void AnalyzeInvocation(SyntaxNodeAnalysisContext context)
{
var invocation = (InvocationExpressionSyntax)context.Node;
var memberAccess = invocation.Expression as MemberAccessExpressionSyntax;
if (memberAccess == null || !memberAccess.IsKind(SyntaxKind.SimpleMemberAccessExpression))
{
return;
}
var ident = memberAccess.Name.Identifier;
if (ident.ToString().ToLower() != "operate")
{
return;
}
var calledFromType = context.SemanticModel.GetTypeInfo(memberAccess.Expression).Type;
if (calledFromType.MetadataName != "Operable")
{
return;
}
context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation()));
}
我会让你失望,但 Roslyn 是一个静态分析器,默认情况下它不可能检索类型、调用等的动态信息。
为了实现这一目标,您需要在 roslyn 下实施自定义动态分析,该分析将调查所有变量赋值、参数传递等,以确定有关对象(类型、方法等)的所有信息,它可以当前时间在代码中。
在下面的例子中要清楚:
public interface IOperable
{
void Operate();
}
public class Operable : IOperable
{
...
}
public class OperableOther : IOperable
{
...
}
...
IOperable ioperable = new Operable();
ioperable.Operate(); // at this time will invoke Operable.Operate();
ioperable = new OperableOther();
ioperable.Operate(); // at this time will OperableOther.Operate();
Roslyn 可以检索关于变量 ioperable
的编译时信息,它是一个 IOperable
,但不能给出它将 Operable
从第一次分配和 OperableOther
从第二。但是如果你会累积所有变量修改等,你可以自己做。