gpt4 book ai didi

c# - 从 MethodInfo 打印方法的完整签名

转载 作者:IT王子 更新时间:2023-10-29 04:12:30 26 4
gpt4 key购买 nike

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

例如,如果您查找 String.Compare(),其中一个重载将打印为:

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

请注意包含所有访问和范围限定符的完整签名以及包括名称在内的完整参数列表。这就是我要找的。我可以编写自己的方法,但如果可能的话,我宁愿使用现有的实现。

最佳答案

2018 年 3 月 22 日更新

我重写了代码,添加了一些测试,并且 uploaded it to GitHub

也可以通过nuget获取

Eltons.ReflectionKit NuGet

回答

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 模板一起使用,为所有 QueryableEnumerable Linq 扩展方法生成重载。

关于c# - 从 MethodInfo 打印方法的完整签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1312166/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com