Is it possible to cast a Dictionary to a consistent intermediate generic type? So I would be able to cast
I had the same situation and created a WrapperDictionary class and a cast extension method. Found it helpful if you also want to make operations with it like remove a item.
Example:
const string TestKey1 = "Key";
const string TestValue1 = "Value";
var dict = new Dictionary();
dict.Add(TestKey1, TestValue1);
var wrapper = dict.CastDictionary();
wrapper.Remove(TestKey1);
Code:
public class DictionaryWrapper : IDictionary
{
#region types
private class EnumeratorWrapper : IEnumerator>
{
private readonly IEnumerator> _enumerator;
private readonly DictionaryWrapper _dictionaryWrapper;
public EnumeratorWrapper(IEnumerator> enumerator, DictionaryWrapper dictionaryWrapper)
{
_enumerator = enumerator;
_dictionaryWrapper = dictionaryWrapper;
}
public void Dispose()
{
_enumerator.Dispose();
}
public bool MoveNext()
{
return _enumerator.MoveNext();
}
public void Reset()
{
_enumerator.Reset();
}
public KeyValuePair Current => _dictionaryWrapper._kvpSourceToTargetFunc(_enumerator.Current);
object IEnumerator.Current => Current;
}
#endregion
#region fields
private readonly IDictionary _dictionary;
private readonly Func _keySourceToTargetFunc;
private readonly Func _keyTargetToSourceFunc;
private readonly Func _valueSourceToTargetFunc;
private readonly Func _valueTargetToSourceFunc;
private readonly Func, KeyValuePair> _kvpSourceToTargetFunc;
private readonly Func, KeyValuePair> _kvpTargetToSourceFunc;
#endregion
#region Construction
public DictionaryWrapper(
IDictionary dict,
Func keySourceToTargetFunc = null,
Func keyTargetToSourceFunc = null,
Func valueSourceToTargetFunc = null,
Func valueTargetToSourceFunc = null)
{
_dictionary = dict;
_keySourceToTargetFunc = keySourceToTargetFunc ?? (i => (TKeyTarget) (object) i);
_keyTargetToSourceFunc = keyTargetToSourceFunc ?? (i => (TKeySource) (object) i);
_valueSourceToTargetFunc = valueSourceToTargetFunc ?? (i => (TValueTarget) (object) i);
_valueTargetToSourceFunc = valueTargetToSourceFunc ?? (i => (TValueSource) (object) i);
_kvpSourceToTargetFunc =
kvp => new KeyValuePair(_keySourceToTargetFunc(kvp.Key), _valueSourceToTargetFunc(kvp.Value));
_kvpTargetToSourceFunc =
kvp => new KeyValuePair(_keyTargetToSourceFunc(kvp.Key), _valueTargetToSourceFunc(kvp.Value));
}
#endregion
#region Interface Members
public IEnumerator> GetEnumerator()
{
return new EnumeratorWrapper(_dictionary.GetEnumerator(), this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(KeyValuePair item)
{
_dictionary.Add(_kvpTargetToSourceFunc(item));
}
public void Clear()
{
_dictionary.Clear();
}
public bool Contains(KeyValuePair item)
{
return _dictionary.Contains(_kvpTargetToSourceFunc(item));
}
public void CopyTo(KeyValuePair[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool Remove(KeyValuePair item)
{
return _dictionary.Remove(_kvpTargetToSourceFunc(item));
}
public int Count => _dictionary.Count;
public bool IsReadOnly => _dictionary.IsReadOnly;
public bool ContainsKey(TKeyTarget key)
{
return _dictionary.ContainsKey(_keyTargetToSourceFunc(key));
}
public void Add(TKeyTarget key, TValueTarget value)
{
_dictionary.Add(_keyTargetToSourceFunc(key), _valueTargetToSourceFunc(value));
}
public bool Remove(TKeyTarget key)
{
return _dictionary.Remove(_keyTargetToSourceFunc(key));
}
public bool TryGetValue(TKeyTarget key, out TValueTarget value)
{
var success = _dictionary.TryGetValue(_keyTargetToSourceFunc(key), out TValueSource result);
value = success ? _valueSourceToTargetFunc(result) : default;
return success;
}
public TValueTarget this[TKeyTarget key]
{
get => _valueSourceToTargetFunc(_dictionary[_keyTargetToSourceFunc(key)]);
set => _dictionary[_keyTargetToSourceFunc(key)] = _valueTargetToSourceFunc(value);
}
public ICollection Keys => _dictionary.Keys.Select(k => _keySourceToTargetFunc(k)).ToList();
public ICollection Values => _dictionary.Values.Select(v => _valueSourceToTargetFunc(v)).ToList();
#endregion
}
public static class DictionaryWrapperExtensions
{
public static IDictionary CastDictionary(this IDictionary dictionary)
{
return new DictionaryWrapper(dictionary);
}
}