Why Html.DropDownListFor requires extra cast?
In my controller I create a list of SelectListItems and store this in the ViewData. When I read the ViewData in my View it gives me an error about incorrect types. If I manually cast the types it works but seems like this should happen automatically. Can someone explain?
Controller:
enum TitleEnum { Mr, Ms, Mrs, Dr };
var titles = new List<SelectListItem>();
foreach(var t in Enum.GetValues(typeof(TitleEnum)))
titles.Add(new SelectListItem()
{ Value = t.ToString(), Text = t.ToS开发者_如何学Pythontring() });
ViewData["TitleList"] = titles;
View:
// Doesn't work
Html.DropDownListFor(x => x.Title, ViewData["TitleList"])
// This Works
Html.DropDownListFor(x => x.Title, (List<SelectListItem>) ViewData["TitleList"])
Because ViewData
is a Dictionary<string, Object>
. How else could you store objects of multiple types in a keyed collection? Anything retrieved from ViewData
without casting will be treated by the compiler as a base Object
.
If I remember correctly, ViewData is an array/collection of objects. This is why the extra cast is needed.
Apparently the compiler will not perform a cast from an object of type object to another type automatically. I expect that results from ViewData are of type object at compile time. Example follows:
// This Fails
object obj = new List<SelectListItem>();
Html.DropDownListFor(x => x.Title, obj);
// This Works
var obj2 = new List<SelectListItem>();
Html.DropDownListFor(x => x.Title, obj2);
It's because of a feature called "static typing". Some love it, others hate it.
what if you change
ViewData["TitleList"] = titles;
to
ViewData["TitleList"] = new SelectListItem()
{ Value = t.ToString(), Text = t.ToString() };
and again try it with:
Html.DropDownListFor(x => x.Title, ViewData["TitleList"])
if this works, the I would agree with Femaref....good question though.
精彩评论