LINQ operations on an IDictionary

Suppose I have the following dictionaries:

private Dictionary<int, string> dic1 = new Dictionary<int, string>() { { 1, "a" }, { 2, "b" }, { 3, "c" } } private Dictionary<SomeEnum, bool> dic2 = new Dictionary<SomeEnum, bool>() { { SomeEnum.First, true }, { SomeEnum.Second, false }, { SomeEnum.Third, false } } 

I want to convert these two dictionaries to Dictionary<string, object>

For example:

  dic1 = new Dictionary<string, object>() { { "1", "a" }, { "2", "b" }, { "3", "c" } } dic2 = new Dictionary<string, object>() { { "First", true }, { "Second", false }, { "Third", false } } 

As you can see, the string key of these dictionaries is just a representation of the string previous ones.

The method responsible for the conversion has the following signature:

  public static object MapToValidType(Type type, object value) { //.... if(typeof(IDictionary).IsAssignableFrom(type)) { //I have to return a Dictionary<string, object> here return ??; } } 

I tried the following:

  ((IDictionary)value).Cast<object>().ToDictionary(i => ...); 

But i was passed to the object, so I cannot access the elements of the key or value. To do this, I would need to apply it to the corresponding KeyValuePair<TKey, TValue> , but I do not know the type of TKey or TValue .

Another solution is as follows:

 IDictionary dic = (IDictionary)value; IList<string> keys = dic.Keys.Cast<object>().Select(k => Convert.ToString(k)).ToList(); IList<object> values = dic.Values.Cast<object>().ToList(); Dictionary<string, object> newDic = new Dictionary<string, object>(); for(int i = 0; i < keys.Count; i++) newDic.Add(keys[0], values[0]); return newDic; 

However, I don't really like this approach, and I'm really looking for a simpler and more friendly single-line LINQ statement.

+7
dictionary c # linq
source share
4 answers

You can try this, not LINQ, although I think you do not need to:

  Dictionary<string, object> ConvertToDictionary(System.Collections.IDictionary iDic) { var dic = new Dictionary<string, object>(); var enumerator = iDic.GetEnumerator(); while (enumerator.MoveNext()) { dic[enumerator.Key.ToString()] = enumerator.Value; } return dic; } 

Or one Linq:

 return iDic.Keys.Cast<object>().ToDictionary(k=> k.ToString(), v=> iDic[v]); 
+1
source share
  static void Main(string[] args) { var blah = KeyToString(dic1); // Verify that we converted correctly foreach (var kvp in blah) { Console.WriteLine("{0} {1}, {2} {3}", kvp.Key.GetType(), kvp.Key, kvp.Value.GetType(), kvp.Value); } } static Dictionary<string, TValue> KeyToString<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> dic1) { return dic1.ToDictionary(kvp => kvp.Key.ToString(), kvp => kvp.Value); } 
+1
source share
 public static IDictionary<string, object> Convert<TKey, TValue>(IDictionary<TKey, TValue> genDictionary) { return genDictionary.Select(kvp => new KeyValuePair<string, object>(kvp.Key.ToString(), (object)kvp.Value)).ToDictionary(x => x.Key, x => x.Value); } 

called:

  var dicIntInt = new Dictionary<int, string>{{123, "asdc"}, {456, "aa"} }; Dictionary<string, object> dicStrObj = Convert(dicIntInt); 

https://dotnetfiddle.net/eY41MQ

0
source share

The trick is to turn your IDictionary into a generic DictionaryEntry type. Then you can use ToDictionary () from System.Linq.

 static Dictionary<string,object> ToDictionary(IDictionary dic) { return dic.Cast<DictionaryEntry> ().ToDictionary ((t) => t.Key.ToString (), (t) => t.Value); } 
-one
source share

All Articles