c# - 从调用中获取函数的精确定义,该调用在接口中定义,但使用 Roslyn 在 C# 中的多个位置实现
问题描述
我看到有很多关于这个主题的问题(C#、Roslyn、Find References and Definitions)。但我仍然没有得到我想要的答案。这里是解释。我有界面:
public interface IRepository {
IEnumerable<X> Abc(long customerIdentity, ...);
}
现在,这个接口由 on 类实现,例如:
public abstract class RepositoryBase : IRepository {
public virtual IEnumerable<X> Abc(long customerIdentity, long? associatedOrderIdentity, ...) { ... }
}
由于这是抽象类,那么其他类可能已经重新定义了这个方法,因为这个方法是虚拟的。此外,接口也可以与其他接口具有属性。
public sealed class CustRepository : RepositoryBase {
public override IEnumerable<X> Abc(long customerIdentity, long? associatedOrderIdentity, ...){ ... }
}
另一件事是这样的
public interface IRepositoryManager {
IRepository Repository { get; }
}
在我的类变量中声明如下:
private IRepositoryManager _repositoryManager;
我可以这样调用方法:
this._repositoryManager.Repository.Abc(customerIdentity, ...)
这是我现在的问题。
- 我如何知道它将在运行时调用哪个方法?我希望它使用 Roslyn 获得定义/声明。我可以使用调用表达式来获取此语句。
- 我应该从直接实现接口的基类中获取方法吗?还是我需要查看继承链中的定义?
请不要关闭这个问题,因为我真的很难得到这个答案。提前致谢!!.
解决方案
目前我有这段代码可以使用 Roslyn API 获取一些信息。
var syntaxTree = await document.GetSyntaxTreeAsync().ConfigureAwait(false);
var sm = await document.GetSyntaxTreeAsync().ConfigureAwait(false);
var semantic = compilation.GetSemanticModel(sm);
var invocations = (from d in syntaxTree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>() select d).ToList();
foreach (var invocation in invocations)
{
// if (!invocation.Expression.ToString().Contains("FindAlertsByLimit") && !invocation.Expression.ToString().Contains("FindAlertsByWindow")) continue;
var ms = semantic.GetSymbolInfo(invocation).Symbol;
if (ms == null) continue;
var referencesTo = await SymbolFinder.FindReferencesAsync(ms, document.Project.Solution).ConfigureAwait(false);
Console.WriteLine(referencesTo);
var de = SymbolFinder.FindDeclarationsAsync(project, referencesTo.First().Definition.Name, false, SymbolFilter.Member).ConfigureAwait(false).GetAwaiter().GetResult().ToList();
Console.WriteLine(de);
// other approach
IMethodSymbol methodSymbol = semantic.GetSymbolInfo(invocation).Symbol as IMethodSymbol;
if (methodSymbol == null) continue;
var syntaxReferences = methodSymbol.DeclaringSyntaxReferences.ToList();
if (!syntaxReferences.Any()) continue;
var declaration = syntaxReferences.First().GetSyntax();
var semanticModel = compilation.GetSemanticModel(declaration.SyntaxTree);
Console.WriteLine(semanticModel.SyntaxTree.FilePath);
}
但似乎我没有得到确切的方法定义。
推荐阅读
- c# - MVC 模型数据未绑定
- minizinc - 约束问题不满足 MiniZinc
- python - 两个端点之间的流式语音
- node.js - 停止回调链并在保存方法 ApostropheCMS 之前发送通知
- eclipse - 直接更新按钮状态JavaFX
- python - 如何计算拼写校正的准确性?
- r - 为什么 data.table 的 order 和 setorder(v) 之间存在这种差异?
- html - 还有其他人在点击最新 Chrome 上的内部数字输入时遇到问题吗?
- javascript - @nestjs/router 的奇怪问题
- docker - 如何将 Azure ML 上的 GPU 与 NVIDIA CUDA 自定义 docker 基础映像一起使用?