I have a class that look like the following:
public class MyClass
{
.开发者_JS百科..
protected void MyMethod()
{
...
string myName = System.Reflection.MethodBase.GetCurrentMethod.Name;
...
}
...
}
The value of myName
is "MyMethod".
Is there a way that I can use Reflection to get a value of "MyClass.MyMethod" for myName
instead?
You could look at the ReflectedType
of the MethodBase
you get from GetCurrentMethod
, i.e.,
MethodBase method = System.Reflection.MethodBase.GetCurrentMethod();
string methodName = method.Name;
string className = method.ReflectedType.Name;
string fullMethodName = className + "." + methodName;
And to get the full method name with parameters:
var method = System.Reflection.MethodBase.GetCurrentMethod();
var fullName = string.Format("{0}.{1}({2})", method.ReflectedType.FullName, method.Name, string.Join(",", method.GetParameters().Select(o => string.Format("{0} {1}", o.ParameterType, o.Name)).ToArray()));
I think these days, it's best to do this:
string fullMethodName = $"{typeof(MyClass).FullName}.{nameof(MyMethod)}";
Extending Ruben's, you can get the full name like this:
var info = System.Reflection.MethodBase.GetCurrentMethod();
var result = string.Format(
"{0}.{1}.{2}()",
info.ReflectedType.Namespace,
info.ReflectedType.Name,
info.Name);
You can add it to a static method that receives a MethodBase parameter and generates the string.
You can get the full name like this:
var fullMethodName = System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.FullName;
In C# 6 you can use nameof
:
string myName = nameof(MyMethod);
You'll have issues when running inside async methods. Here's how to fix that:
If you need to fully qualify the class name, you'll have to use DeclaringType.FullName
instead of DeclaringType.Name
This code won't work nicely for anonymous or lambda methods.
using System.Runtime.CompilerServices;
static string GetMethodContextName() {
var name = new StackTrace().GetFrame(1).GetMethod().GetMethodContextName();
return name;
}
static string GetMethodContextName(this MethodBase method) {
if (method.DeclaringType.GetInterfaces().Any(i => i == typeof(IAsyncStateMachine))) {
var generatedType = method.DeclaringType;
var originalType = generatedType.DeclaringType;
var foundMethod = originalType.GetMethods(
BindingFlags.Instance | BindingFlags.Static
| BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.DeclaredOnly)
.Single(m => m.GetCustomAttribute<AsyncStateMachineAttribute>()?.StateMachineType == generatedType);
return foundMethod.DeclaringType.Name + "." + foundMethod.Name;
} else {
return method.DeclaringType.Name + "." + method.Name;
}
}
Here's an example usage:
class Program {
static void Main(string[] args) {
// outputs Program.Main
Console.WriteLine(GetMethodContextName());
}
}
Thanks for the posts above, they helped me to create a strong type binding system for MVC 4 HTMLHelpers as follows.
public static MvcHtmlString StrongTypeBinder(this HtmlHelper htmlhelper, Expression<Func<object, string>> SomeLambda)
{
var body = SomeLambda.Body;
var propertyName = ((PropertyInfo)((MemberExpression)body).Member).Name;
HtmlString = @"
<input type='text' name='@Id' id='@Id'/>
";
HtmlString = HtmlString.Replace("@Id", propertyName);
var finalstring = new MvcHtmlString(HtmlString);
return finalstring;
}
To use the code above in any CSHTML View:
@Html.StrongTypeBinder(p=>Model.SelectedDate)
This allows me to bind any property in a ViewModel to any HTML element type I want. In the example above, I an binding the name field for the selected data posted back after user makes selection. The viewmodel after the post back automatically shows the selected value.
精彩评论