Jay Sun
Jay Sun

Reputation: 1601

Trouble passing in function parameter in C#

Right now, users on our MVC web app can make a bunch of ajax calls to the server. Currently we're handling them all uniquely without a global wrapper/handler method. I'd like to change that, but I don't have much experience with function delegates in C#.

Ideally, I'd like for it to be designed something like below:

public class GenericService
{
    public PageViewModel EditPage(PageViewModel model)
    {
        ....
    }

    public JsonResult JsonAjaxRequest(Func<Object, Object> serviceCall, Object data)
    {
        try
        {
            return new JsonResult() { Data = new { status = "ok", data = serviceCall(data) } };
        }
        catch
        {
            return new JsonResult() { Data = new { status = "error", message = "The server encountered an unknown error." } };
        }
    }

Now in my controller, I have the following code:

private readonly GenericService _service;

public JsonResult PageEdit(PageViewModel model)
{
    return Json(_service.JsonAjaxRequest(x=>_service.EditPage(model), model));
}

I keep getting a cannot convert from method group to system.func<object, object> error and an invalid arguments compile error and I'm not sure why. Please advise.

Upvotes: 0

Views: 176

Answers (1)

Servy
Servy

Reputation: 203829

I would suggest changing your method so that it is generic, rather than just using object everywhere:

public JsonResult JsonAjaxRequest<TIn, TOut>(Func<TIn, TOut> serviceCall, TIn data)
{
    try
    {
        return new JsonResult() { Data = new { status = "ok", data = serviceCall(data) } };
    }
    catch
    {
        return new JsonResult() { Data = new { status = "error", message = "The server encountered an unknown error." } };
    }
}

Using this the generic arguments can be inferred based on the lambda or method group you provide as a parameter. For a lambda it shouldn't be an issue, but when passing in a method group directly it can help with a few edge cases. It also means that the parameter you provide to the function is strongly typed, so you don't need to cast it.

The only way that you could get a compiler error like the one you mentioned after making this change would be if you used a method that either accepts some number of parameters other than one (namely zero or 2+) or if it returns void instead of some value.

Upvotes: 2

Related Questions