首页 > 解决方案 > 我可以将方法标识符(例如:MyClass.MyMethod)作为 C# 中的方法参数吗?

问题描述

方法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作为单独的参数传递,那就太好了。

更新更多上下文和示例:
我的目标是在 Razor 视图中指定控制器和操作时避免使用魔法字符串。这是我目前如何通过检查[Action]动作属性并从控制器中修剪“控制器”后缀来执行此操作的示例。但是你可以看到它很冗长。

<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>

标签: c#.netasp.net-core.net-core

解决方案


您可以通过反射来做到这一点,将方法名称作为字符串传递,然后使用Type.GetMethod来获取方法,然后Invoke使用类型实例调用该方法。

但是,最好的办法是使用委托。具体来说,您可以执行以下操作:

public static string MyMethod(Func<IActionResult> func)

接着:

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

在内部MyMethod,您可以像任何其他方法一样调用它,即func().

也就是说,您在这里最终要实现的目标尚不清楚且值得怀疑。你不能只调用HomeController.Index; 你需要一个HomeController实例。手动更新控制器几乎总是错误的,所以一般来说,可能有更好的方法来实现你想要的。

换句话说,你这里似乎有一个 XY 问题。您正在尝试执行 X,并且您已确定 Y 是执行此操作的方法(这里,尝试传递方法引用并出于某种原因调用它)。但是,你也不知道如何做 Y。而不是询问X,即您实际上需要帮助的事情,而是询问Y,这几乎可以肯定首先不是做X的好方法。给我们一些关于 X 的更多信息,你真正想要的东西,我们可能会给你一个更好的方法来实现它。


推荐阅读