Я пытаюсь написать анализатор 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()));
}