3

Here is the full implementation I am considering:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using 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 ValueTypes and other Objects with == overloads versus Objects with default reference equality).

Community
  • 1
  • 1
Stephen Swensen
  • 22,107
  • 9
  • 81
  • 136
  • Why would you want to cast to dynamic? Simply call `x.Key.Equals(selectedKey)` and let it determine it for you. – Tejs Jun 07 '11 at 21:18
  • @Tejs - yep, that's pretty much my question: which should I do 1) `(dynamic)x.Key == (dynamic)selectedKey` 2) `x.Key.Equals(selectedKey)` 3) `(object)x.Key == (object)selectedKey`. I thought #2 as you suggested would be fine, but then I doubted my confidence and thought I might be missing something. – Stephen Swensen Jun 07 '11 at 21:31
  • @Tejs - and alas, there are even more options already given. – Stephen Swensen Jun 07 '11 at 21:32

2 Answers2

4

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) });
Bala R
  • 107,317
  • 23
  • 199
  • 210
  • Thanks @Bala R - how would this differ from just using `x.Key.Equals`? I also wonder if I were to change `dic` to a `Dictionary`, whether there would be any merit to doing `dic.Comparer.Equals(selectedKey)`... – Stephen Swensen Jun 07 '11 at 21:41
  • 2
    @Stephen `x.Key.Equals()` is not type safe since it takes an object; `EqualityComparer.Default.Equals()` is. – Bala R Jun 07 '11 at 21:47
1

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");
Jess
  • 42,368
  • 6
  • 37
  • 51