Reputation: 2125
I am trying to get the System.Reflection.MethodInfo metadata of a method using the member name from an Xml Documentation file entry.
Here is the basic code. I have left out the boilerplate to get the values from the Member.name string for brevity.
// 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();
}
This works fine for methods with only one signature or with a few simple signatures like below.
<member name="M:Library.Extensions.ConvertExtensions.ToInt(System.String,System.Int32)"></member>
<member name="M:Library.Extensions.ConvertExtensions.ToBool(System.String)"></member>
But breaks down for more complicated examples, such as an method overloads. The strings from the doc XML for the more complicated types are just not parsable by 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>
Currently, I can get the MemberInfo for about half of the entries in my xml documentation file.
Is there a reliable, generic way to get the MethodInfo object using the member.name from an XML document file?
Upvotes: 0
Views: 424
Reputation: 2028
This topic might be clearer as How to get MethodInfo with many overloading functions and complicated parameter
.
I'm assuming that you did parsed XML documentation successful and got the string like this
NetCoreScripts.StackOverFlow.ReflectionTopic.MyObject(System.String,System.String,System.Boolean)
Over there you can use any separator method to split into 2 elements:
First is: NetCoreScripts.StackOverFlow.ReflectionTopic.MyObject
Second is array of: System.String
, System.String
, System.Boolean
(3 params must be the same order)
private static Type[] ToTypeArray(string[] typeNames)
{
var types = new List<Type>();
foreach (string name in typeNames)
{
types.Add(Type.GetType(name));
}
return types.ToArray();
}
I reuse your ToTypeArray
and create a model
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) { }
}
}
Main calling method will be
public static void GetMyMethod(Type type, string[] arr)
{
var parameters = ToTypeArray(arr);
var method = type.GetMethod("DoMore", parameters);
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" });
}
To know exactly there name, I suggest using full name on pair testing, write and read Xml would be easier
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
Hope it helps
Upvotes: 0