As I was reading ASP.Net MVC 3 introduction, I noticed how HTML helper constructs an action link and provides parameters to the link. For example:
@Html.ActionLink(“Edit”, "Edit", new { id =123, name = "some name" })
Note the last parameter is an anonymous type. This makes sense because HTML helper can’t anticipate the exact information layouts to be passed. The anonymous type gives us flexibility of passing arbitrary key-value pairs using a simply syntax (after all a full-scale Dictionary could have been chosen but that doesn’t resonate with Razor’s simply-flow philosophy). However, as the anonymous type has method boundary, the parameter will be passed as an object to the consuming method. How to use the values contained by the anonymous type across function boundaries? There are several options, as presented below. Note that you don’t need to do any of the following when using ASP.Net MVC 3. The following is a generic discussion of different possible ways of consuming anonymous types across function boundaries.
- Use reflection. The anonymous type is a real type, you can use regular reflection methods to retrieve its properties:
static void Main(string[] args) { Test(new { id = 123, name = "ABC" }); } static void Test(object val) { Type type = val.GetType(); foreach (var prop in type.GetProperties()) Console.WriteLine(prop.Name + "=" + prop.GetValue(val,null)); }
- Use a cast. This method uses the fact that two separately declared anonymous types are considered compatible types if they had same property layout:
static void Test(object val) { var dict = Cast(val, new { id = 0, name = "" }); Console.WriteLine("id=" + dict.id); Console.WriteLine("name=" + dict.name); } static T Cast<T>(object o, T type) { return (T)o; }
- Use dynamic type. Dynamic type gives us the simplest syntax to consume a anonymous type passed in as an object, as shown in the following modified Test() method (with the price of losing compile-time type check):
static void Test(object val) { dynamic dict = val; Console.WriteLine("id=" + dict.id); Console.WriteLine("name=" + dict.name); }
0 comments:
Post a Comment