Converting an generic IDictionary to an ASP.NET MVC IEnumerable<SelectListItem>: choosing the Selected item
Here is the full implementation I am considering:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
usin开发者_如何学运维g System.Web.Mvc;
namespace Utils {
public static class IDictionaryExt {
public static IEnumerable<SelectListItem> ToSelectListItems<T, R>(this IDictionary<T, R> dic, T selectedKey) {
return dic.Select(x => new SelectListItem() { Text = x.Value.ToString(), Value = x.Key.ToString(), Selected=(dynamic)x.Key == (dynamic)selectedKey });
}
}
}
Notice the equality check using the dynamic casts: (dynamic)x.Key == (dynamic)selectedKey
. Is this the best way to check equality between selectedKey
and x.Key
here? Based on @Gabe's comment in Operator '==' can't be applied to type T?, I believe it is: overload resolution is deferred to to runtime, but we do get "normal" overload resolution (i.e. considering ValueType
s and other Object
s with ==
overloads versus Object
s with default reference equality).
The best way to handle this situation is to use EqualityComparer<T>.Default
return dic.Select(x => new SelectListItem() { Text = x.Value.ToString(), Value = x.Key.ToString(), Selected= EqualityComparer<T>.Default.Equals(x.Key, selectedKey) });
If you don't want to use x.Key.Equals
you can pull the comparison into a Func:
public static IEnumerable<SelectListItem> ToSelectListItems<T, R>(this IDictionary<T, R> dic, Func<T, bool> selectedKey)
{
return dic.Select(x => new SelectListItem() { Text = x.Value.ToString(), Value = x.Key.ToString(), Selected = selectedKey(x.Key) });
}
then call it as so:
var list = sampleDictionary.ToSelectListItems(k => k == "Some Key");
精彩评论