Generi c Способ получения MethodInfo для методов, использующих Xml Документация Member.Name - PullRequest
0 голосов
/ 03 марта 2020

Я пытаюсь получить метаданные System.Reflection.MethodInfo метода, используя имя члена из Xml записи файла документации.

Вот базовый c код. Я оставил шаблон для получения значений из строки Member.name для краткости.

// The following variables are all parsed out of the 'name' string from the 
// XML documentation for each entry (from 1st example below):
// Member: "ToInt"
// Namespace: "Library.Extensions"
// ClassName: "ConvertExtensions"    
// AssemblyToDocument: Library 
// ParameterArray: "System.String,System.Int32"

// Uses the GetMethod() method with the parameter 'types' overload
// as there can be multiple signatures for a particular Method name.  

string typeName = $"{Namespace}.{ClassName}, {AssemblyToDocument}";        
var types = ToTypeArray(ParameterArray);
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.ToInt(System.String,System.Int32)"></member>

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

Но ломается для более сложных примеров, таких как перегрузки метода. Строки из do c XML для более сложных типов просто не обрабатываются Type.GetType (string).

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

В настоящее время я могу получить MemberInfo примерно для половины записей в моем xml файле документации.

Существует ли надежный универсальный c способ получения объекта MethodInfo с использованием member.name из файла XML документа?

1 Ответ

0 голосов
/ 03 марта 2020

Эта topi c может быть понятнее как 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.String, System.String, System.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

Надеюсь, это поможет

...