Get types used inside a C# method body

后端 未结 7 870
鱼传尺愫
鱼传尺愫 2020-12-01 16:12

Is there a way to get all types used inside C# method?

For example,

public int foo(string str)
{
    Bar bar = new Bar();
    string x = \"test\";
           


        
7条回答
  •  孤城傲影
    2020-12-01 17:04

    I just posted an extensive example of how to use Mono.Cecil to do static code analysis like this.

    I also show a CallTreeSearch enumerator class that can statically analyze call trees, looking for certain interesting things and generating results using a custom supplied selector function, so you can plug it with your 'payload' logic, e.g.

        static IEnumerable SearchMessages(TypeDefinition uiType, bool onlyConstructions)
        {
            return uiType.SearchCallTree(IsBusinessCall,
                   (instruction, stack) => DetectTypeUsage(instruction, stack, onlyConstructions));
        }
    
        internal class TypeUsage : IEquatable
        {
            public TypeReference Type;
            public Stack Stack;
    
            #region equality
            // ... omitted for brevity ...
            #endregion
        }
    
        private static TypeUsage DetectTypeUsage(
            Instruction instruction, IEnumerable stack, bool onlyConstructions)
        {
            TypeDefinition resolve = null;
            {
                TypeReference tr = null;
    
                var methodReference = instruction.Operand as MethodReference;
                if (methodReference != null)
                    tr = methodReference.DeclaringType;
    
                tr = tr ?? instruction.Operand as TypeReference;
    
                if ((tr == null) || !IsInterestingType(tr))
                    return null;
    
                resolve = tr.GetOriginalType().TryResolve();
            }
    
            if (resolve == null)
                throw new ApplicationException("Required assembly not loaded.");
    
            if (resolve.IsSerializable)
                if (!onlyConstructions || IsConstructorCall(instruction))
                    return new TypeUsage {Stack = new Stack(stack.Reverse()), Type = resolve};
    
            return null;
        }
    

    This leaves out a few details

    • implementation of IsBusinessCall, IsConstructorCall and TryResolve as these are trivial and serve as illustrative only

    Hope that helps

提交回复
热议问题