Есть тестовое консольное приложение.
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.
Комментариев нет:
Отправить комментарий