如何解决Roslyn C#:如何通过方法访问所有字段和属性及其所属的类
我希望为我的方法计算对外部数据的访问指标。此外,我想知道我的方法是从哪些对象访问字段和属性的,以确定功能嫉妒代码气味的存在。
对于此示例:
public class DoctorService
{
private List<Doctor> _doctors;
public Doctor FindAvailableDoctor(DateRange timeSpan)
{
foreach (Doctor d in _doctors)
{
foreach(DateRange holiday in d.HolidayDates)
{
d.Test = null;
if (!holiday.OverlapsWith(timeSpan)) return d;
}
}
return null;
}
}
,特别是FindAvailableDoctor方法,我想建立一个包含字段的列表,这些字段将包含Doctor类的HolidayDates和Test属性。我还想知道这两个属性都属于Doctor类(由类名及其名称空间标识)。
我编写了以下代码来完成此操作:
var accessedFields = member.DescendantNodes().OfType<MemberAccessExpressionSyntax>();
foreach (var field in accessedFields)
{
var symbol = semanticModel.GetSymbolInfo(field.Expression).Symbol;
switch(symbol)
{
case ILocalSymbol local:
fields.Add(new CaDETMember { Name = local.Type + "|" + local.Name });
break;
case IPropertySymbol prop:
fields.Add(new CaDETMember { Name = prop.ContainingSymbol + "|" + field.ToString() });
break;
case IParameterSymbol param:
fields.Add(new CaDETMember { Name = param.Type + "|" + field.ToString() });
break;
};
}
,并开始摆弄Symbol API的字段。但是,此解决方案既不干净,我也很肯定会因为非平凡的代码而错过某些边缘情况。
提取一种方法访问的字段和属性名称的更好方法是什么,这样我也可以知道所访问的字段和属性属于哪个类?
编辑:根据杰森的回答,我采用了以下解决方案:
var accessedFields = semanticModel.GetOperation(member).Descendants().OfType<IMemberReferenceOperation>();
foreach (var field in accessedFields)
{
fields.Add(new CaDETMember {Name = field.Member.ToDisplayString()});
}
return fields;
解决方法
您的方法实际上是一种非常好的方法,因此不要为此感到难过。第二种方法是使用IOperation API。如果调用SemanticModel.GetOperation()可以得到一棵IOperation树,则可以遍历该树,它表示在代码中各个点处执行的语义操作。特别是,有一个IMemberReferenceOperation指向被引用的成员。像这样:
var memberReferences = semanticModel.GetOperation(methodSyntax).Descendants().OfType<IMemberReferenceOperation>()
将让您查看这些内容,然后从那里获取符号。本地访问也有其他操作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。