Reputation: 5276
The way nameof()
works, I can write
var s = nameof(HomeController.Index);
Can I make my own compile-time method that works the same way and can take the same input? For example:
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);
Update for context:
More specifically I would like to be able to make a helper method to be used in a Razor view. For example, I might call MyMethod(HomeController.Index)
to return a string listing the controller name and the action name. It would be nice to be able to make such a method without having to pass both the controller type HomeController
and the method name Invoke
as separate parameters.
Update for more context and example:
My goal is to avoid magic strings when specifying controllers and actions in Razor views. Here's an example of how I am doing this currently by checking for the [Action]
attribute on actions and trimming of the "Controller" suffix from controllers. But you can see that it's verbose.
<a asp-action="@(ControllerHelpers.GetActionName<HomeController>(nameof(HomeController.Index)))" asp-controller="@(ControllerHelpers.GetRouteName<HomeController>())">Link to Home</a>
I'm looking for a way to do something like this
<a asp-action="@ControllerHelpers.GetActionName(HomeController.Index)" asp-controller="@(ControllerHelpers.GetRouteName<HomeController>())">Link to Home</a>
and perhaps eventually my own tag helper like this. But even here I'd like to avoid having to separately pass both the controller and the action name (just for concision).
<a asp-controller-action="HomeController.Index">Link to Home</a>
Upvotes: 0
Views: 74
Reputation: 3554
I'm not 100% sure what you're asking for, but here's an example of how to do something like what you're asking for using delegates (MS delegate guide):
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");
}
}
Sample output:
C:\Workspace\SampleApp\bin\Debug>SampleApp.exe
Method1
First
Second
Upvotes: 0
Reputation: 239450
You can do this via reflection, passing the method name as a string, and then using Type.GetMethod
to get the method and then call Invoke
on that, with the type instance.
However, the better thing to do here is to use a delegate. Specifically, you can do something like:
public static string MyMethod(Func<IActionResult> func)
And then:
var s = MyMethod(() => controller.Index());
Inside MyMethod
, you'd invoke this like any other method, i.e. func()
.
That said, what you're trying to ultimately achieve here is unclear and suspect. You can't just invoke HomeController.Index
; you need a HomeController
instance. Manually newing up a controller, is pretty much always wrong, so there's probably a better way to achieve what you want, in general.
In other words, you seem to have an XY problem here. You're trying to do X, and you've decided Y is the way to do that (here, trying to pass a method reference and invoke that for some reason). But, you don't know how to do Y, either. Instead of asking about X, i.e. the thing you actually need help with, you're asking about Y, which almost assuredly isn't even a good way to do X, in the first place. Give us some more info on X, the thing you actually want, and we can probably give you a better method to achieve that.
Upvotes: 1