I want to call a function that generates a function, but I don’t know the type parameter until I call the generated function like so:
ActionResult Foo() {
IEnumerable<MyObject> list = GetList();
var orderBy = OrderBy(list); // <-- HOW DO I WRITE OR DO THIS;
switch(Request.QueryString["sortBy"]) {
case "Name":
return orderBy<string>(o => o.Name); // <-- SO I CAN MAKE THIS CALL
case "TrackingNumber":
return orderBy<int>(o => o.TrackingNumber); // <-- AND THIS ONE
default:
return View(list);
}
}
I won’t know the type of T until I call the returned function. I imagine something like this to generate the function, it wraps list in a closure so that I don’t have to keep passing it around.
Func<Func<MyObject,T>,ActionResult> OrderBy<T>(IEnumerable<MyObject> list) {
Func<Func<MyObject,T>, ActionResult> f = orderBy => {
return View(Request.QueryString["sortDir"] == "d"
? list.OrderBy<MyObject, T>(orderBy)
: list.OrderByDescending<MyObject, T>(orderBy));
};
return f;
}
Update:
I know there are better ways to do this. I want to know how I can wrap this list in a closure and return a function that has a generic type I don’t know about ahead of time. For example, since I can’t return the generic type function without knowing the type, is there some type I can replace it with?
The trick is to identify the type that you care about that both types have in common. In this case, it’s
IComparable. You’re sorting, and bothstrings andints areIComparable.You’re also making the problem a lot more complicated than it needs to be. You don’t need so many
Func‘s that returnFunc‘s. You can simplify.Also you don’t want ASP.NET MVC classes to permeate your entire application. Keep that stuff in the controllers and let the code that does the real work take parameters so it doesn’t know it’s running in ASP.NET MVC or in the web and can be unit tested.