簡體   English   中英

Roslyn C#:如何獲取方法訪問的所有字段和屬性(及其所屬類)

[英]Roslyn C#: How to get all fields and properties (and their belonging class) accessed by a method

我希望為我的方法計算訪問外部數據指標。 此外,我想知道我的方法從哪些對象訪問字段和屬性以確定是否存在功能羡慕代碼氣味。

對於這個例子:

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 class 的 HolidayDates 和 Test 屬性。我還想知道這兩個屬性都屬於 Doctor class(由 class 名稱和它的命名空間)。

我編寫了以下代碼來完成此操作:

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;
    };
}

並開始擺弄符號 API 的字段。但是,這個解決方案既不干凈,而且我很確定會錯過一些非平凡代碼的邊緣情況。

提取方法訪問的字段和屬性名稱有什么更好的方法,這樣我也可以知道訪問的字段和屬性屬於哪個class?

編輯:根據 Jason 的回答,我采用了以下解決方案:

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() ,它會為您提供一棵 IOperations 樹,您可以遍歷它表示在代碼中的各個點執行的語義操作。 特別是有一個IMemberReferenceOperation將指向被引用的成員。 所以像:

var memberReferences = semanticModel.GetOperation(methodSyntax).Descendants().OfType<IMemberReferenceOperation>()

會讓你看看那些,然后從那里得到符號。 本地訪問還有其他操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM