Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有了IMethodSymbol,在Roslyn中是否可以计算出该方法中使用/调用的所有方法和字段?_C#_Roslyn - Fatal编程技术网

C# 有了IMethodSymbol,在Roslyn中是否可以计算出该方法中使用/调用的所有方法和字段?

C# 有了IMethodSymbol,在Roslyn中是否可以计算出该方法中使用/调用的所有方法和字段?,c#,roslyn,C#,Roslyn,我有IMethodSymbol对象,我想找出该方法使用/调用的所有方法和字段 我已经用Mono.Cecil做过了。然而,这还不够好,因为任何涉及动态类型的代码都只是反射。因此,检查二进制代码在这里是无用的-我们必须检查源代码 因此,我知道该方法的IMethodSymbol使用动态参数(它调用Binder.InvokeMember)。我知道源代码分析可以告诉我调用了什么方法 我熟悉SymbolFinder类,并且能够使用它的FindReferencesAsync方法。但我看不出如何将其用于我的目的

我有
IMethodSymbol
对象,我想找出该方法使用/调用的所有方法和字段

我已经用Mono.Cecil做过了。然而,这还不够好,因为任何涉及动态类型的代码都只是反射。因此,检查二进制代码在这里是无用的-我们必须检查源代码

因此,我知道该方法的
IMethodSymbol
使用动态参数(它调用
Binder.InvokeMember
)。我知道源代码分析可以告诉我调用了什么方法

我熟悉
SymbolFinder
类,并且能够使用它的
FindReferencesAsync
方法。但我看不出如何将其用于我的目的,即,给定该方法,找到它使用的所有符号

我错过了什么

编辑1

因此,我想出了如何获得顶级操作:

var op = model.GetOperation(method.DeclaringSyntaxReferences[0].GetSyntax());

其中,
model
是相应的
SemanticModel
实例,
method
是我的
IMethodSymbol
。但实际上有无数种操作。我需要一种方便的方法来导航它们。我想我需要的是
OperationWalker
。将继续探索。

我找到了方法-
OperationWalker

就我而言,我有以下“walker”(正在进行的工作):

我只对动态调用感兴趣,因为非动态调用是由
Mono.Cecil
提供给我的

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Operations;
using System;
using System.Collections.Generic;

namespace CSTool
{
    public class DynamicOperationWalker : OperationWalker
    {
        public readonly List<IMethodSymbol> Result = new();
        public readonly List<(SyntaxNode,string)> Unresolved = new();

        public override void VisitDynamicIndexerAccess(IDynamicIndexerAccessOperation operation)
        {
            throw new NotImplementedException();
        }

        public override void VisitDynamicInvocation(IDynamicInvocationOperation operation)
        {
            var memberReferenceOp = (IDynamicMemberReferenceOperation)operation.Operation;
            switch (memberReferenceOp.Instance.Type)
            {
                case INamedTypeSymbol type:
                    {
                        var memberName = memberReferenceOp.MemberName;
                        var members = type.GetMembers(memberName);
                        if (members.Length > 1)
                        {
                            throw new NotImplementedException();
                        }
                        Result.Add((IMethodSymbol)members[0]);
                        break;
                    }

                case IDynamicTypeSymbol dynamicType:
                    Unresolved.Add((operation.Syntax, memberReferenceOp.MemberName));
                    break;
            }
        }

        public override void VisitDynamicMemberReference(IDynamicMemberReferenceOperation operation)
        {
            throw new NotImplementedException();
        }

        public override void VisitDynamicObjectCreation(IDynamicObjectCreationOperation operation)
        {
            throw new NotImplementedException();
        }
    }
}
var op = model.GetOperation(methodSymbol.DeclaringSyntaxReferences[0].GetSyntax());
var walker = new DynamicOperationWalker();
walker.Visit(op);