2010-06-03 2 views
30

У меня есть класс, который выглядеть следующим:Использование System.Reflection, чтобы получить Method Полное имя

public class MyClass 
{ 

... 

    protected void MyMethod() 
    { 
    ... 
    string myName = System.Reflection.MethodBase.GetCurrentMethod.Name; 
    ... 
    } 

... 

} 

Значение myName является «MyMethod».

Есть ли способ, которым я могу использовать Reflection для получения значения «MyClass.MyMethod» вместо myName?

+1

Исправление: оно должно быть System.Reflection.MethodBase.GetCurrentMethod() Имя – aads

ответ

50

Вы можете посмотреть на ReflectedType из MethodBase вы получаете от GetCurrentMethod, т.е.

MethodBase method = System.Reflection.MethodBase.GetCurrentMethod(); 
string methodName = method.Name; 
string className = method.ReflectedType.Name; 

string fullMethodName = className + "." + methodName; 
+0

Именно то, что я искал.. Благодаря! –

+0

Просто обратите внимание, что «ReflectedType» не учитывает полиморфизм времени выполнения, как можно было ожидать. – user2864740

4

Расширение Рубена, вы можете получить полное имя, как это:

var info = System.Reflection.MethodBase.GetCurrentMethod(); 
var result = string.Format(
       "{0}.{1}.{2}()", 
       info.ReflectedType.Namespace, 
       info.ReflectedType.Name, 
       info.Name); 

Вы можете добавить его к статическому методу, который получает параметр MethodBase и генерирует строку.

4

Вы можете получить полное имя, как это:

var fullMethodName = System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.FullName; 
14

И чтобы получить полное имя методы с параметрами:

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())); 
+0

+1 Определенно самое полезное решение.Включение FullName помогает определить класс, когда ваша база кода повторяет имена классов в разных пространствах имен. И в том числе параметры помогают различать перегруженные методы. –

2

Спасибо за вышеуказанные должности, они помогли мне создать сильный типа для MVC 4 HTMLHelpers следующим образом.

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; 

    } 

Чтобы использовать код, указанный выше в любом CSHTML Вид:

@Html.StrongTypeBinder(p=>Model.SelectedDate) 

Это позволяет мне привязать любое свойство в ViewModel для любого типа HTML элемента я хочу. В приведенном выше примере я привязываю поле имени для выбранных данных, отправленных после того, как пользователь делает выбор. Модель просмотра после обратной записи автоматически отображает выбранное значение.

2

В C# 6 вы можете использовать nameof:

string myName = nameof(MyMethod); 
+1

Да, но это возвращает только имя, а не полное имя. В приведенном примере он возвращает строку '' MyMethod '', а не' MyClass.MyMethod''. – Matt

5

Я думаю, что в эти дни, то лучше сделать это:

string fullMethodName = $"{typeof(MyClass).FullName}.{nameof(MyMethod)}"; 
+1

Искали это, чтобы я мог регистрировать квалифицированные имена, и это подход, который я принял. Просто потому, что он маленький, простой и делает то, что мне нужно. – onesixtyfourth

0

Вы будете иметь проблемы при работе внутри методов асинхронными. Вот как это исправить:

Если вам необходимо полностью определить имя класса, вы должны будете использовать DeclaringType.FullName вместо DeclaringType.Name

Этот код не будет работать хорошо для анонимных или лямбда-методов.

static string GetMethodContextName() { 
    var name = new StackTrace().GetFrame(1).GetMethod().GetMethodContextName(); 
} 

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(Instance | Static | Public | NonPublic | DeclaredOnly) 
      .Single(m => m.GetCustomAttribute<AsyncStateMachineAttribute>()?.StateMachineType == generatedType); 
     return foundMethod.DeclaringType.Name + "." + foundMethod.Name; 
    } else { 
     return method.DeclaringType.Name + "." + method.Name; 
    } 
} 

Вот пример использования:

class Program { 
    static void Main(string[] args) { 
     // outputs Program.Main 
     Console.WriteLine(GetMethodContextName()); 
    } 
} 
Смежные вопросы