从MethodInfo打印方法的完整签名

.NET BCL中是否有任何现有的功能在运行时打印方法的完整签名(如您在Visual Studio ObjectBrowser中看到的内容 - 包括参数名称)使用MethodInfo提供的信息?从MethodInfo打印方法的完整签名

因此,举例来说,如果你看看String.Compare()的一个重载将打印为:

public static int Compare(string strA, int indexA, string strB, int indexB, int length, bool ignoreCase, System.Globalization.CultureInfo culture) 

注意与所有访问和范围预选赛完整签名的存在,以及一个完整的参数列表包括名称。这是我正在寻找的。我可以编写自己的方法,但如果可能的话,我宁愿使用现有的实现。

回答:

不幸的是我不相信有一个内置的方法可以做到这一点。你最好的,将是调查的MethodInfo类

编辑创建自己的签名:我只是做这个

MethodBase mi = MethodInfo.GetCurrentMethod(); 

mi.ToString();

,你会得到

无效的主要(System.String [ ])

这可能不是你要找的,但它很接近。

这个怎么样

public static class MethodInfoExtension 

{

public static string MethodSignature(this MethodInfo mi)

{

String[] param = mi.GetParameters()

.Select(p => String.Format("{0} {1}",p.ParameterType.Name,p.Name))

.ToArray();

string signature = String.Format("{0} {1}({2})", mi.ReturnType.Name, mi.Name, String.Join(",", param));

return signature;

}

}

var methods = typeof(string).GetMethods().Where(x => x.Name.Equals("Compare"));

foreach(MethodInfo item in methods)

{

Console.WriteLine(item.MethodSignature());

}

这是结果

的Int32比较(字符串STRA,的Int32 指数A,字符串STRB,的Int32 indexB,的Int32 长度,StringComparison comparisonType)

回答:

签出MethodBase上的GetParameters()方法。这会给你关于参数的信息,包括参数的名字。我不相信存在一个预先存在的方法来打印出名称,但使用ParameterInfo []来构建应该是微不足道的。

如何:

public string GetSignature(MethodInfo mi) 

{

if(mi == null)

return "";

StringBuilder sb = new StringBuilder();

if(mi.IsPrivate)

sb.Append("private ");

else if(mi.IsPublic)

sb.Append("public ");

if(mi.IsAbstract)

sb.Append("abstract ");

if(mi.IsStatic)

sb.Append("static ");

if(mi.IsVirtual)

sb.Append("virtual ");

sb.Append(mi.ReturnType.Name + " ");

sb.Append(mi.Name + "(");

String[] param = mi.GetParameters()

.Select(p => String.Format(

"{0} {1}",p.ParameterType.Name,p.Name))

.ToArray();

sb.Append(String.Join(", ",param));

sb.Append(")");

return sb.ToString();

}

回答:

using System.Text; 

namespace System.Reflection

{

public static class MethodInfoExtensions

{

/// <summary>

/// Return the method signature as a string.

/// </summary>

/// <param name="method">The Method</param>

/// <param name="callable">Return as an callable string(public void a(string b) would return a(b))</param>

/// <returns>Method signature</returns>

public static string GetSignature(this MethodInfo method, bool callable = false)

{

var firstParam = true;

var sigBuilder = new StringBuilder();

if (callable == false)

{

if (method.IsPublic)

sigBuilder.Append("public ");

else if (method.IsPrivate)

sigBuilder.Append("private ");

else if (method.IsAssembly)

sigBuilder.Append("internal ");

if (method.IsFamily)

sigBuilder.Append("protected ");

if (method.IsStatic)

sigBuilder.Append("static ");

sigBuilder.Append(TypeName(method.ReturnType));

sigBuilder.Append(' ');

}

sigBuilder.Append(method.Name);

// Add method generics

if(method.IsGenericMethod)

{

sigBuilder.Append("<");

foreach(var g in method.GetGenericArguments())

{

if (firstParam)

firstParam = false;

else

sigBuilder.Append(", ");

sigBuilder.Append(TypeName(g));

}

sigBuilder.Append(">");

}

sigBuilder.Append("(");

firstParam = true;

var secondParam = false;

foreach (var param in method.GetParameters())

{

if (firstParam)

{

firstParam = false;

if (method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false))

{

if (callable)

{

secondParam = true;

continue;

}

sigBuilder.Append("this ");

}

}

else if (secondParam == true)

secondParam = false;

else

sigBuilder.Append(", ");

if (param.ParameterType.IsByRef)

sigBuilder.Append("ref ");

else if (param.IsOut)

sigBuilder.Append("out ");

if (!callable)

{

sigBuilder.Append(TypeName(param.ParameterType));

sigBuilder.Append(' ');

}

sigBuilder.Append(param.Name);

}

sigBuilder.Append(")");

return sigBuilder.ToString();

}

/// <summary>

/// Get full type name with full namespace names

/// </summary>

/// <param name="type">Type. May be generic or nullable</param>

/// <returns>Full type name, fully qualified namespaces</returns>

public static string TypeName(Type type)

{

var nullableType = Nullable.GetUnderlyingType(type);

if (nullableType != null)

return nullableType.Name + "?";

if (!(type.IsGenericType && type.Name.Contains('`')))

switch (type.Name)

{

case "String": return "string";

case "Int32": return "int";

case "Decimal": return "decimal";

case "Object": return "object";

case "Void": return "void";

default:

{

return string.IsNullOrWhiteSpace(type.FullName) ? type.Name : type.FullName;

}

}

var sb = new StringBuilder(type.Name.Substring(0,

type.Name.IndexOf('`'))

);

sb.Append('<');

var first = true;

foreach (var t in type.GetGenericArguments())

{

if (!first)

sb.Append(',');

sb.Append(TypeName(t));

first = false;

}

sb.Append('>');

return sb.ToString();

}

}

}

这实际上是处理一切,包括扩展方法。从http://www.pcreview.co.uk/forums/getting-correct-method-signature-t3660896.html得到了一个开始。

我用它在一个T4模板的tandum中为所有的QueryableEnumerable Linq扩展方法生成过载。

以上是 从MethodInfo打印方法的完整签名 的全部内容, 来源链接: utcz.com/qa/257767.html

回到顶部