Могу ли я взять идентификатор метода (например, MyClass.MyMethod) в качестве параметра метода в C#? - PullRequest
0 голосов
/ 30 апреля 2020

Как работает nameof(), я могу написать

var s = nameof(HomeController.Index);

Могу ли я создать свой собственный метод времени компиляции, который работает так же и может принимать те же данные? Например:

public static string MyMethod(Something input) // I'm not sure what Something should be
{
    // do something with input to get method info
}

... // elsewhere in code

var s = MyMethod(HomeController.Index);

Обновление для контекста:
Более конкретно, я хотел бы иметь возможность создать вспомогательный метод для использования в представлении Razor. Например, я мог бы вызвать MyMethod(HomeController.Index), чтобы вернуть строку, содержащую имя контроллера и имя действия. Было бы неплохо создать такой метод, не передавая тип контроллера HomeController и имя метода Invoke как отдельные параметры.

Обновление для большего контекста и примера:
Моя цель - избегать магических c строк при указании контроллеров и действий в представлениях Razor. Вот пример того, как я делаю это в настоящее время, проверяя атрибут [Action] в действиях и обрезая суффикс «Controller» из контроллеров. Но вы можете видеть, что это многословно.

<a asp-action="@(ControllerHelpers.GetActionName<HomeController>(nameof(HomeController.Index)))" asp-controller="@(ControllerHelpers.GetRouteName<HomeController>())">Link to Home</a>

Я ищу способ сделать что-то вроде этого

<a asp-action="@ControllerHelpers.GetActionName(HomeController.Index)" asp-controller="@(ControllerHelpers.GetRouteName<HomeController>())">Link to Home</a>

и, возможно, в конечном итоге мой собственный помощник тегов, как это. Но даже здесь я хотел бы избежать необходимости отдельно передавать и контроллер, и имя действия (просто для краткости).

<a asp-controller-action="HomeController.Index">Link to Home</a>

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Вы можете сделать это с помощью отражения, передав имя метода в виде строки, а затем используя Type.GetMethod, чтобы получить метод, а затем вызвать Invoke для этого с экземпляром типа.

Однако, Лучше всего использовать делегата. В частности, вы можете сделать что-то вроде:

public static string MyMethod(Func<IActionResult> func)

И затем:

var s = MyMethod(() => controller.Index());

Внутри MyMethod, вы будете вызывать это как любой другой метод, то есть func().

Тем не менее, то, что вы пытаетесь в конечном итоге достичь здесь, неясно и подозрительно. Вы не можете просто вызвать HomeController.Index; вам нужен экземпляр HomeController. Обновление контроллера вручную, в значительной степени всегда неправильно, поэтому, возможно, есть лучший способ добиться того, чего вы хотите, в общем.

Другими словами, у вас, похоже, проблема XY Вот. Вы пытаетесь сделать X, и вы решили, что Y - способ сделать это (здесь, пытаясь передать ссылку на метод и вызвать ее по какой-то причине). Но вы тоже не знаете, как это сделать. Вместо того, чтобы спрашивать о X, то есть о чем вам на самом деле нужна помощь, вы спрашиваете о Y, который почти наверняка даже не является хорошим способом сделать X, во-первых. Дайте нам больше информации о X, о чем вы действительно хотите, и мы, возможно, сможем дать вам лучший способ добиться этого.

0 голосов
/ 30 апреля 2020

Я не на 100% уверен, что вы просите, но вот пример того, как сделать что-то наподобие того, что вы просите, используя делегатов ( Руководство для делегатов MS ):

 class MethodRunner
    {
        // use delegates to define the method signature that you'll operate on
        public delegate void NoArgFormat();
        public delegate void OneStringArgFormat(String arg);

        //You can accept delegates as function arguments, then call them
        //with a "live" object instance
        public void RunMyMehtod(NoArgFormat methodToRun)
        {
            methodToRun();//runs the methd passed in
        }
        public void RunMyStringArgMethod(OneStringArgFormat methodToRun, String arg)
        {
            methodToRun(arg);
        }
    }
    class Program
    {
        //This matches to "NoArgFormat" delegate definition
        public void Method1()
        {
            Console.WriteLine("Method1");
        }

        //This matches the OneStringArgFormat
        public void Method2(String arg)
        {
            Console.WriteLine(arg);
        }
        static void Main(string[] args)
        {
            Program p = new Program();
            MethodRunner mr = new MethodRunner();
            mr.RunMyMehtod(p.Method1);
            mr.RunMyStringArgMethod(p.Method2, "First");
            mr.RunMyStringArgMethod(p.Method2, "Second");
        }
    }

Пример вывода:

C: \ Workspace \ SampleApp \ bin \ Debug> SampleApp.exe

Method1
Первый
Второй

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...