Я знаю, что на сайте есть несколько ответов по этому поводу, и прошу прощения, если это каким-либо образом дублируется, но все ответы, которые я нашел, не делают то, что я пытаюсь делать.
Я пытаюсь указать информацию о методе, чтобы получить имя безопасным способом, не используя строки. Итак, я пытаюсь извлечь его с помощью выражения.
Скажем, я хочу получить имя метода в этом интерфейсе:
public interface IMyInteface
{
void DoSomething(string param1, string param2);
}
В настоящее время я могу получить имя с помощью ЭТОГО метода:
MemberInfo GetMethodInfo<T>(Expression<Action<T>> expression)
{
return ((MethodCallExpression)expression.Body).Method;
}
Я могу вызвать вспомогательный метод следующим образом:
var methodInfo = GetMethodInfo<IMyInteface>(x => x.DoSomething(null, null));
Console.WriteLine(methodInfo.Name);
Но я ищу версия, в которой я могу получить имя метода без указания параметров (null, null)
следующим образом:
var methodInfo = GetMethodInfo<IMyInteface>(x => x.DoSomething);
Но все попытки не компилируются
Есть ли способ сделать это?
Если ваше приложение разрешит зависимость от Moq (или подобной библиотеки), вы можете сделать что-то вроде этого:
class Program
{
static void Main(string[] args)
{
var methodName = GetMethodName<IMyInteface>(x => new Action<string,string>(x.DoSomething));
Console.WriteLine(methodName);
}
static string GetMethodName<T>(Func<T, Delegate> func) where T : class
{
// http://code.google.com/p/moq/
var moq = new Mock<T>();
var del = func.Invoke(moq.Object);
return del.Method.Name;
}
}
public interface IMyInteface
{
void DoSomething(string param1, string param2);
}
Если вы в порядке с оператором nameof()
, вы можете использовать следующий подход.
Одним из преимуществ является отсутствие необходимости разворачивать дерево выражений или предоставлять значения по умолчанию или беспокоиться о наличии ненулевого экземпляра типа с помощью метода.
// As extension method
public static string GetMethodName<T>(this T instance, Func<T, string> nameofMethod) where T : class
{
return nameofMethod(instance);
}
// As static method
public static string GetMethodName<T>(Func<T, string> nameofMethod) where T : class
{
return nameofMethod(default);
}
Использование:
public class Car
{
public void Drive() { }
}
var car = new Car();
string methodName1 = car.GetMethodName(c => nameof(c.Drive));
var nullCar = new Car();
string methodName2 = nullCar.GetMethodName(c => nameof(c.Drive));
string methodName3 = GetMethodName<Car>(c => nameof(c.Drive));