使用Xml文档Member.Name获取方法的MethodInfo的通用方法

问题描述 投票:0回答:1

我正在尝试使用Xml文档文件条目中的成员名称来获取方法的System.Reflection.MethodInfo元数据。

这里是基本代码。为了简便起见,我省略了样例以从Member.name字符串获取值。

// Member, Namespace, ClassName, AssemblyToDocument, ParameterArray variables all parsed out of XML Member.name string. See examples below.

string typeName = $"{Namespace}.{ClassName}, {AssemblyToDocument}";

var types = ToTypeArray(ParameterArray);


// Get MethodInfo - Need to use GetMethod with parameter types overload as there can be multiple signatures  

MethodInfo methodInfo =  typeName.GetMethod(Member, types);


private Type[] ToTypeArray(string[] typeNames)
{
    var types = new List<Type>();

    foreach (string name in typeNames)
    {
        types.Add(Type.GetType(name));
    }
    return types.ToArray();
}

这对于仅具有一个签名或具有一些简单签名的方法(如下所示)很好。

<member name="M:Library.Extensions.ConvertExtensions.ToBool(System.String)"></member>

<member name="M:Library.Extensions.ConvertExtensions.ToInt(System.String,System.Int32)"></member>

但是对于更复杂的示例,例如方法重载或名称中的字符串未直接转换为GetType调用的情况,会发生故障。

<member name="M:Library.Extensions.ConvertExtensions.ToBool(System.String,System.String,System.Boolean)"></member>

<member name="M:Library.Extensions.IEnumerableExtensions.ElementInOrDefault``1(System.Collections.Generic.IEnumerable{``0},System.Int32)"></member>

[目前,我可以获取xml文档文件中大约一半条目的MemberInfo。 Xml字符串member.name的字符串参数与为获取类型而需要调用的实际字符串之间存在一些差异。

是否有可靠的通用方法使用XML文档文件中的member.name获取MethodInfo对象?

c# system.reflection xml-documentation methodinfo
1个回答
0
投票

此主题可能更清楚地表示为How to get MethodInfo with many overloading functions and complicated parameter

我假设您成功解析了XML文档,并得到了这样的字符串

NetCoreScripts.StackOverFlow.ReflectionTopic.MyObject(System.String,System.String,System.Boolean)

在那儿,您可以使用任何分隔符方法将其分成2个元素:

首先是:NetCoreScripts.StackOverFlow.ReflectionTopic.MyObject

第二个数组是:System.StringSystem.StringSystem.Boolean(3个参数必须具有相同的顺序)

    private static Type[] ToTypeArray(string[] typeNames)
    {
        var types = new List<Type>();

        foreach (string name in typeNames)
        {
            types.Add(Type.GetType(name));
        }
        return types.ToArray();
    }

我重用您的ToTypeArray并创建模型

namespace NetCoreScripts.StackOverFlow.ReflectionTopic
{
    public class MyObject
    {
        public void DoMore(int parameter) { }
        public void DoMore(string str1, string str2, bool bool1) { }
        public void DoMore(string str, int num) { }
        public void DoMore(List<string> parameter) { }
        public void DoMore(List<string> parameter, int param) { }
        public void DoMore(List<List<string>> parameter, bool? nullableBool, bool isTrue) { }
    }
}

主调用方法将是

    public static void GetMyMethod(Type type, string[] arr)
    {
        var parammeters = ToTypeArray(arr);
        var method = type.GetMethod("DoMore", parammeters);
        Console.WriteLine(method.Name);
    }

    public static void MainFunc()
    {
        var type = Type.GetType("NetCoreScripts.StackOverFlow.ReflectionTopic.MyObject");
        GetMyMethod(type, new string[] { "System.Int32" });
        GetMyMethod(type, new string[] { "System.String", "System.String", "System.Boolean" });
        GetMyMethod(type, new string[] { "System.String", "System.Int32" });
        GetMyMethod(type, new string[] { "System.Collections.Generic.List`1[[System.String]]" });
        GetMyMethod(type, new string[] { "System.Collections.Generic.List`1[[System.String]]", "System.Int32" });
        GetMyMethod(type, new string[] { "System.Collections.Generic.List`1[[System.Collections.Generic.List`1[[System.String]]]]", "System.Nullable`1[[System.Boolean]]", "System.Boolean" });
    }

要确切知道那里的名字,我建议在配对测试中使用全名,写和读Xml会更容易

        Console.WriteLine(typeof(bool?).FullName); 
        //System.Nullable`1[[System.Boolean, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]

        Console.WriteLine(Type.GetType("System.Nullable`1[[System.Boolean]]").FullName);
        //For shorter

希望有帮助

© www.soinside.com 2019 - 2024. All rights reserved.