Мне было интересно, можно ли получить метод и имя класса введенной функции метода. Я постараюсь быть более конкретным:
У меня есть класс Form1.cs, в котором я создал этот метод:
public static void CalculateTime(Action<string> funcToCalc, string where)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
funcToCalc(where);
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
// gets the textbox name
TextBox t = Application.OpenForms["Form1"].Controls["textBox1"] as TextBox;
// writes in the textbox of this form this string
t.AppendText(funcToCalc.Method.Name + " executed in " + elapsedMs + "ms;\n");
}
В этом классе я вызываю этот метод следующим образом:
CalculateTime( Class1.CreateStuff, textPath.Text);
CalculateTime( Class2.CreateStuff, textPath.Text);
Я хочу распечатать что-то вроде
"MyClass1.CreateStuff executed in 100ms"
"MyClass2.CreateStuff executed in 75ms"
и т.п.
На данный момент мой метод распечатывает
"CreateStuff executed in 100ms"
"CreateStuff executed in 75ms"
что не позволяет мне распознать класс вызываемого метода.
Есть ли способ получить имя класса в этом конкретном случае?
Обратите внимание, что если в моем CalculateTime я звоню
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name;
Я получаю строку "Form1".
Вызов System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name; из формы form1, конечно же, вернет form1..
Мне просто интересно, возможно ли это без передачи параметров методу





Самый простой способ — запросить свойство делегата Method, которое указывает на выполняемый метод.
Обратите внимание, что, хотя он работает для статических членов и членов экземпляра, он не обязательно имеет смысл при вызове анонимного делегата (когда возвращается бессмысленное имя метода, созданного компилятором):
using System;
public class Foo1
{
// static
public static void Method( string s )
{
}
}
public class Foo2
{
// instance
public void Method( string s )
{
}
}
public class Program
{
public static void Main(string[] args)
{
PrintDelegateInfo( Foo1.Method );
PrintDelegateInfo( new Foo2().Method );
PrintDelegateInfo( (Action<string>)(s => {}) );
}
private static void PrintDelegateInfo(Action<string> funcToCall)
{
var methodInfo = funcToCall.Method;
var name = string.Format( "{0}.{1}", methodInfo.DeclaringType.Name, methodInfo.Name );
Console.WriteLine( "{0} called", name );
}
}
Выход:
Foo1.Method called
Foo2.Method called
Program.<Main>b__0 called
Вы можете использовать в самом действии метод расширения GetMethodInfo(Delegate), чтобы получить MethodInfo для делегата. Предполагая, что вы не передаете анонимный типизированный делегат, такой как функция Lambda, вы можете использовать этот MethodInfo для получения типа класса с помощью DeclaringType следующим образом:
public static void CalculateTime(Action<string> funcToCalc, string where)
{
var miAction = funcToCalc.GetMethodInfo();
var actionContainingType = miAction.DeclaringType;
var watch = System.Diagnostics.Stopwatch.StartNew();
funcToCalc(where);
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
// gets the textbox name
TextBox t = Application.OpenForms["Form1"].Controls["textBox1"] as TextBox;
// writes in the textbox of this form this string
t.AppendText($"{actionContainingType.Name}.{funcToCalc.Method.Name} executed in {elapsedMs} ms;\n");
}
Какой класс вы ожидаете для единодушных действий?