Страницы

Поиск по вопросам

четверг, 13 декабря 2018 г.

Узнать, есть ли атрибут у вызывающего метода?

Есть тестовое консольное приложение.
internal class Program { [MyTest("TestDescription")] static void Main(string[] args) { TestSchmest ta = new TestSchmest(); ta.GetSomeThingMethod();
Console.ReadKey(); } }
internal class TestSchmest { public void GetSomeThingMethod([CallerMemberName] string methodName = "") { Console.WriteLine("\t - In hell we die!!!"); WhoCalledMe(); Console.WriteLine(); Console.WriteLine("Method \"GetSomeThingMethod\" was called by {0}.", methodName);
// methodName.GetAttribute ??? }
private void WhoCalledMe([CallerMemberName] string methodName = "") { Console.WriteLine("\t - For what?!"); Console.WriteLine(); Console.WriteLine("Method \"WhoCalledMe\" was called by {0}.", methodName);
// methodName.GetAttribute ??? } }
public class MyTestAttribute : Attribute { protected string Description;
public MyTestAttribute(string description) { Description = description; } }
Сначала вызывается метод GetSomeThingMethod класса TestSchmest, который в свою очередь вызывает метод WhoCalledMe. Можно ли как-то из методов класса TestSchmest узнать, указан ли атрибут у вызывающего их метода или нет.
Т.е. ta.GetSomeThingMethod() должен показать, что атрибут есть, а WhoCalledMe() что его нет.
Название класса, в котором вызываются методы (в данном случае Program) может быть неизвестно.


Ответ

С помощью класса StackTrace можно получить предыдущий кадр стека, относящийся к вызвавшему методу. Атрибут CallerMemberName при этом не требуется.
public void GetSomeThingMethod() { string methodName = ""; MyTestAttribute attribute = null;
var st = new StackTrace(); if (st.FrameCount > 1) { var prevFrame = st.GetFrame(1); // получаем кадр стека для вызвавшего метода var caller = prevFrame.GetMethod(); // получаем сам вызвавший метод methodName = caller.Name;
var attributes = caller.GetCustomAttributes(typeof(MyTestAttribute), false); if (attributes.Length > 0) attribute = (MyTestAttribute)attributes[0]; }
Console.WriteLine("\t - In hell we die!!!"); WhoCalledMe(); Console.WriteLine(); Console.WriteLine("Method \"GetSomeThingMethod\" was called by {0}.", methodName);
if (attribute != null) Console.WriteLine("Attribute is present."); }
Результат:
Method "GetSomeThingMethod" was called by Main. Attribute is present.

Комментариев нет:

Отправить комментарий