简体   繁体   English

Mono.Cecil :获取通用参数名称

[英]Mono.Cecil : Get generic parameter name

We are coding a project that check if there are references problems within our nuget packages.我们正在编写一个项目来检查我们的 nuget 包中是否存在引用问题。 So we decided to use Mono.cecil to extract every method calls, and then check if we find a method that suits the call.所以我们决定使用 Mono.cecil 来提取每个方法调用,然后检查是否找到适合调用的方法。

While extracting every method calls, I obtain for example在提取每个方法调用时,我获得例如

string fullName = !!0 Extensions::MinBy(System.Collections.Generic.IEnumerable`1<!!0>,System.Func`2<!!0,!!1>)

Where !!0 and !!1 are generics arguments for the method :其中 !!0 和 !!1 是方法的泛型参数:

public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source,
Func<TSource, TKey> selector)

I was wondering if there was a way to obtain instead :我想知道是否有办法获得:

TSource Extensions::MinBy(System.Collections.Generic.IEnumerable`1<TSource>,System.Func`2<TSource, TKey>)
                AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(path);
                foreach (ModuleDefinition module in assembly.Modules)
                {
                    foreach (TypeDefinition type in module.Types)
                    {
                        foreach (MethodDefinition method in type.Methods.Where(x => x.HasBody))
                        {
                            foreach (var il in method.Body.Instructions)
                            {
                                if (il.OpCode == OpCodes.Call || il.OpCode == OpCodes.Calli || il.OpCode == OpCodes.Callvirt)
                                {
                                    var mRef = il.Operand as MethodReference;

                                    string fullName = mRef.GetElementMethod().FullName; // This is where i get !!0 Extensions::MinBy(System.Collections.Generic.IEnumerable`1<!!0>,System.Func`2<!!0,!!1>)

                                    **//TODO : Find a way to obtain parameters names**

                                }
                            }
                        }
                    }
                }

Thanks a lot非常感谢

I am not sure if Mono.Cecil provides this functionality.我不确定 Mono.Cecil 是否提供此功能。 It does appear that type parameters coming from the declaring type uses the type parameter name (instead of the IL syntax !0, !1, etc).来自声明类型的类型参数似乎确实使用了类型参数名称(而不是 IL 语法 !0、!1 等)。

That being said, you can do something like (remember this is just for inspiration):话虽如此,您可以执行以下操作(请记住,这只是为了获得灵感):

var genMethod = mRef as GenericInstanceMethod;
if (genMethod != null)
{
    for(var i = 0 ; i < genMethod.GenericArguments.Count; i++)
        fullName = fullName.Replace($"!!{i}",  genMethod.GenericArguments[i].Name);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM