Синтаксические типы (например, MethodDeclarationSyntax
) работают только на на синтаксическом уровне. На этом уровне не известно, реализует ли метод Dispose
IDisposable
. Это потому, что вы еще не знаете, какие методы есть у IDisposable
. Более того, вы даже не знаете, существует ли IDisposable
, является ли он классом или интерфейсом, или каково его полное имя. (Это System.IDisposable
? Или MyNamespace.IDisposable
?)
Чтобы получить такую информацию, вам нужно перейти на семантический уровень, как вы уже догадались.
Я не нашел способа напрямую перейти от метода к интерфейсу, если это не явная реализация интерфейса (РЕДАКТИРОВАТЬ: это потому, что это не всегда возможно, см. Комментарий Кевина). Но вы можете перейти от типа к реализации определенного метода интерфейса.
Итак, если вы хотите узнать, что определенный MethodSymbol
реализует IDisposable.Dispose()
, вы можете сделать что-то вроде:
SyntaxTree unit = SyntaxTree.ParseCompilationUnit(code);
MethodDeclarationSyntax method = …;
var compilation = Compilation.Create("test")
.AddReferences(new AssemblyFileReference(typeof(object).Assembly.Location))
.AddSyntaxTrees(unit);
SemanticModel model = compilation.GetSemanticModel(unit);
MethodSymbol methodSymbol = (MethodSymbol)model.GetDeclaredSymbol(method);
var typeSymbol = methodSymbol.ContainingType;
var idisposableDisposeSymbol = model.BindExpression(
0, Syntax.ParseExpression("System.IDisposable.Dispose()")).Symbol;
var implementation = typeSymbol.FindImplementationForInterfaceMember(
idisposableDisposeSymbol);
bool methodImplementsDispose = methodSymbol == implementation;