Convert enum to Dictionary<int,string> but string is the description attribute - c#

I try to convert an enum to Dictionary int is the value and string is the description of the value.
I already have a function that gets the enum description by it's value but I don't how to use it with the enum iteration I have:
public static IDictionary<int, string> ConvertEnumToDictionary<K>()
{
Dictionary<int, string> mydic = new Dictionary<int, string>();
foreach (K foo in Enum.GetValues(typeof(K)))
{
//???
mydic.Add((int)foo, GetEnumDescription(foo));
}
}
public static string GetEnumDescription(Enum value)
{
// Get the Description attribute value for the enum value
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
public enum Lu_LanguageTypes
{
[Description("Hebrew")]
he = 1,
[Description("Englishj")]
en = 2,
[Description("Spanish")]
es = 3
}

You can modify ConvertEnumToDictionary method a little bit and apply where K : Enum generic constraint (available from C# 7.3) and cast Enum value to K before passing to GetEnumDescription method
public static IDictionary<int, string> ConvertEnumToDictionary<K>() where K : Enum
{
var mydic = new Dictionary<int, string>();
foreach (var foo in Enum.GetValues(typeof(K)))
{
mydic.Add((int)foo, GetEnumDescription((K)foo));
}
return mydic;
}
Example of the usage, which gives a dictionary with 3 key-value pairs
var result = ConvertEnumToDictionary<Lu_LanguageTypes>();
Another option is to add constraint to IConvertible interface as well (since Enum type implements it) and avoid casting
public static IDictionary<int, string> ConvertEnumToDictionary<K>() where K : Enum, IConvertible
{
var mydic = new Dictionary<int, string>();
foreach (K foo in Enum.GetValues(typeof(K)))
{
mydic.Add(foo.ToInt32(null), GetEnumDescription(foo));
}
return mydic;
}

Related

C# How to pass a generic type of enum as a variable into a function...?

I want to make a static generic function to handle all cases about that make a Dictionary and return it.
I write a function like this.
public static Dictionary<string, T> GetDictionaryNameToEnum<T>(IEnumerable<T> type)
{
Dictionary<string, T> dict = new Dictionary<string, T> ();
foreach (T value in Enum.GetValues(typeof(T))) {
dict.Add (value.ToString (), value);
}
return dict;
}
but when i invoke the function like this.
public enum FlipType
{
normal,
y4,
x4,
y4x4,
}
static Dictionary<string, FlipType> FlipNameToType = new Dictionary<string, FlipType> ();
public static FlipType GetFlipType(string flipTypeName)
{
if (FlipNameToType == null) {
FlipNameToType = GameUtil.GetDictionaryNameToEnum (FlipType);
}
return FlipNameToType [flipTypeName];
}
I get a compile issue.
Error CS0118: 'macehead.GameWrapperBrickSet.FlipType' is a 'type' but a 'variable' was expected (CS0118) (Assembly-CSharp)
How can I invoke this function? And Can I do it like this Or there has a better way.
I hope it can help you。
class Program
{
static void Main(string[] args)
{
Console.Write(GetFlipType("normal"));
}
static Dictionary<string, FlipType> FlipNameToType = new Dictionary<string, FlipType>();
public static FlipType GetFlipType(string flipTypeName)
{
if (FlipNameToType == null || FlipNameToType.Count == 0)
{
FlipNameToType = default(FlipType).ToDictionaryMembersEx();
}
return FlipNameToType[flipTypeName];
}
public enum FlipType
{
normal,
y4,
x4,
y4x4,
}
}
public static class EnumExtensions
{
public static Dictionary<string, TEnum> ToDictionaryMembersEx<TEnum>(this TEnum source) where TEnum : struct, IConvertible
{
Dictionary<string, TEnum> dict = new Dictionary<string, TEnum>();
foreach (TEnum value in Enum.GetValues(typeof(TEnum)))
{
dict.Add(value.ToString(), value);
}
return dict;
}
}
This error is expectable. You pass FlipType to your method while it is a type.
This would be a correct usage of your method:
FlipNameToType = GameUtil.GetDictionaryNameToEnum<FlipType>(null);
null is because usage of IEnumerable<T> type method parameter is absolutely unclear, and you actually don't use it inside your method. Perhaps, you just need to remove this parameter.
Your code is overcomplicated and unclear, in general.
If you need to know FlipType by its name, then you don't need to store values in Dictionary, you can just use Enum.Parse or Enum.TryParse:
public static FlipType GetFlipType(string flipTypeName)
{
FlipType parsed; // in C# 7.0 can be simplified into 'out FlipType parsed'
if (!Enum.TryParse<FlipType>(flipTypeName, out parsed)
{
throw new OutOfRangeException(nameof(flipTypeName));
}
return parsed;
}
Note that this code throws OutOfRangeException if flipTypeName does not match any FlipType enumeration value. However, your code does the same - it would throw exception if no key has is found in Dictionary<string, T>.

Understanding Protobuf-net serialization and deserialization of properties

I'm doing some tests with the Protobuf-net serializer and was experimenting with the serialization of properties. Basically i wanted to store a dictionary(string, int) as a dictionary(string, string) and then on deserialization convert the (string, string) back to a (string, int). However, much to my surprise it goes through the getter on TestDictionary on deserialization (and then threw a null reference exception) which confused me a lot. I would think it goes through the setter on deserialization. So, essentially I'm not sure how property serialization is supposed to function. The simple test class I wrote is below:
[ProtoContract]
public class Class1
{
[ProtoMember(2)]
public int test;
public Dictionary<string, int> testDictionary;
//public Dictionary<string, string> testDictionaryString;
[ProtoMember(3)]
private string test2;
[ProtoMember(4)]
private string test3;
[ProtoMember(5)]
private string test4;
public Class1()
{}
public Class1(int test)
{
this.test = test;
this.testDictionary = new Dictionary<string, int>();
for (int i = 0; i < test; i++)
{
this.testDictionary.Add("a" + i.ToString(), i);
}
test2 = (test + 1).ToString();
test3 = (test + 2).ToString();
test4 = (test + 3).ToString();
}
[ProtoMember(1)]
public Dictionary<string, string> TestDictionary
{
get
{
Dictionary<string, string> temp = new Dictionary<string, string>();
foreach (KeyValuePair<string, int> pair in this.testDictionary)
{
temp.Add(pair.Key, pair.Value.ToString());
}
return temp;
}
set
{
testDictionary = new Dictionary<string, int>();
foreach (KeyValuePair<string, string> pair in value)
{
testDictionary.Add(pair.Key, Convert.ToInt32(pair.Value));
}
}
}
For the purposes of serialization, dictionaries are treated just like lists.
You can imagine the default list serialization as something like (assuming that there is a set available):
var list = obj.TheProperty;
if(list == null) {
list = new TheListType();
obj.TheProperty = list;
}
do {
list.Add(DeserializeTheItemType(reader));
} while ({still that field})
However, you can influence it. Simply adding OverwriteTrue = true may be sufficient for your needs:
[ProtoMember(1, OverwriteList = true)]
public Dictionary<string, string> TestDictionary {...}
This should now do something more like:
var list = new TheListType();
do {
list.Add(DeserializeTheItemType(reader));
} while ({still that field})
obj.TheProperty = list;
An important consequence here, however, is that Merge will no longer work in the usual expected way.
As a side note: your get/set should probably pass nulls through, so that if testDictionary is null, TestDictionary returns null; and if TestDictionary is set to null, then testDictionary is set to null.

Generate dynamic object from dictionary with C # Reflection

I've been researching a bit about reflections in C # and would like to know if I use a dictionary with keys-values ​​can create an object with the variable with the name of each key in the dictionary and their values​​, the key value of that dictionary.
I have a method that does the opposite, that extracts an object from a dictionary, this dictionary contains the keys and the class properties and their values​​, the value of the properties.
I wonder how to do this if possible.
Below is my method, which extracts a dictionary of an object:
protected Dictionary<String, String> getObjectProperty(object objeto)
{
Dictionary<String, String> dictionary = new Dictionary<String, String>();
Type type = objeto.GetType();
FieldInfo[] field = type.GetFields();
PropertyInfo[] myPropertyInfo = type.GetProperties();
String value = null;
foreach (var propertyInfo in myPropertyInfo)
{
if (propertyInfo.GetIndexParameters().Length == 0)
{
value = (string)propertyInfo.GetValue(objeto, null);
value = value == null ? null : value;
dictionary.Add(propertyInfo.Name.ToString(), value);
}
}
return dictionary;
}
If you've already got a dictionary, I'd avoid reflection and just use DynamicObject
For example:
public class DynamicDictionary : DynamicObject
{
private readonly Dictionary<string, object> dictionary;
public DynamicDictionary(Dictionary<string, object> dictionary)
{
this.dictionary = dictionary;
}
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
return dictionary.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
dictionary[binder.Name] = value;
return true;
}
}
Which can be used as follows:
dynamic x = new DynamicDictionary(
new Dictionary<string, object> {{"Name", "Peter"}});
Console.WriteLine(x.Name);
I am not sure if this is what you're looking for, but judging by your question, I think you want to
instantiate types at run time from the types located in a dictionary, which will be obtained by providing a key.
If that is so, then you can create the following class which will hold key-value pairs of strings which will be your keys, and Types which will represent your values which will be instantiated.
class DictionaryActivator
{
Dictionary<string, Type> Dictionary = new Dictionary<string, Type>();
public DictionaryActivator()
{
Dictionary.Add("MyCar", typeof(Car));
Dictionary.Add("MyHouse", typeof(House));
Dictionary.Add("MyFruit", typeof(Fruit));
Dictionary.Add("MyComputer", typeof(Computer));
}
public T GetInstance<T>(string type, params object[] parameters)
{
if (parameters.Count() == 0)
{
return (T)Activator.CreateInstance(Dictionary[type]);
}
else
{
return (T)Activator.CreateInstance(Dictionary[type], parameters.ToArray());
}
}
}
You can also create four test classes to test this setup.
class House
{
public int Number = 25;
}
class Car
{
public double Price = 50000;
}
class Fruit
{
public string Name = "Apple";
}
class Computer
{
public string Cpu { get; set; }
public string Gpu { get; set; }
public Computer(string cpu, string gpu)
{
Cpu = cpu;
Gpu = gpu;
}
}
Once this is done, you can run the following lines of code to get all the types from the dictionary, instantiate them and cast them to appropriate types. As you might notice, the last Computer example is showing you how to add multiple parameters (in this case two) to the newly created instance and return it as an instance of type object.
In the end you can cast it to the Computer type so you can check that the constructor parameters actually went to the corresponding properties.
class Program
{
static void Main()
{
var source = new DictionaryActivator();
Console.WriteLine(source.GetInstance<Car>("MyCar").Price);
Console.WriteLine(source.GetInstance<House>("MyHouse").Number);
Console.WriteLine(source.GetInstance<Fruit>("MyFruit").Name);
var computer = source.GetInstance<object>("MyComputer", "Fast CPU", "Fast GPU");
Console.WriteLine((computer as Computer).Cpu);
Console.WriteLine((computer as Computer).Gpu);
Console.Read();
}
}
Since ExpandoObject is a dictionary, you can use this extension function:
public static object With(this IDictionary<string, object> obj, IDictionary<string,object> additionalProperties)
{
foreach (var name in additionalProperties.Keys)
obj[name] = additionalProperties[name];
return obj;
}
Usage:
var dynamicObj = new System.Dynamic.ExpandoObject().With(myDictionary);

How to convert object to Dictionary<TKey, TValue> in C#?

How do I convert a dynamic object to a Dictionary<TKey, TValue> in C# What can I do?
public static void MyMethod(object obj)
{
if (typeof(IDictionary).IsAssignableFrom(obj.GetType()))
{
// My object is a dictionary, casting the object:
// (Dictionary<string, string>) obj;
// causes error ...
}
else
{
// My object is not a dictionary
}
}
The above answers are all cool. I found it easy to json serialize the object and deserialize as a dictionary.
var json = JsonConvert.SerializeObject(obj);
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
I don't know how performance is effected but this is much easier to read. You could also wrap it inside a function.
public static Dictionary<string, TValue> ToDictionary<TValue>(object obj)
{
var json = JsonConvert.SerializeObject(obj);
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, TValue>>(json);
return dictionary;
}
Use like so:
var obj = new { foo = 12345, boo = true };
var dictionary = ToDictionary<string>(obj);
I use this helper:
public static class ObjectToDictionaryHelper
{
public static IDictionary<string, object> ToDictionary(this object source)
{
return source.ToDictionary<object>();
}
public static IDictionary<string, T> ToDictionary<T>(this object source)
{
if (source == null)
ThrowExceptionWhenSourceArgumentIsNull();
var dictionary = new Dictionary<string, T>();
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))
AddPropertyToDictionary<T>(property, source, dictionary);
return dictionary;
}
private static void AddPropertyToDictionary<T>(PropertyDescriptor property, object source, Dictionary<string, T> dictionary)
{
object value = property.GetValue(source);
if (IsOfType<T>(value))
dictionary.Add(property.Name, (T)value);
}
private static bool IsOfType<T>(object value)
{
return value is T;
}
private static void ThrowExceptionWhenSourceArgumentIsNull()
{
throw new ArgumentNullException("source", "Unable to convert object to a dictionary. The source object is null.");
}
}
the usage is just to call .ToDictionary() on an object
Hope it helps.
public static KeyValuePair<object, object > Cast<K, V>(this KeyValuePair<K, V> kvp)
{
return new KeyValuePair<object, object>(kvp.Key, kvp.Value);
}
public static KeyValuePair<T, V> CastFrom<T, V>(Object obj)
{
return (KeyValuePair<T, V>) obj;
}
public static KeyValuePair<object , object > CastFrom(Object obj)
{
var type = obj.GetType();
if (type.IsGenericType)
{
if (type == typeof (KeyValuePair<,>))
{
var key = type.GetProperty("Key");
var value = type.GetProperty("Value");
var keyObj = key.GetValue(obj, null);
var valueObj = value.GetValue(obj, null);
return new KeyValuePair<object, object>(keyObj, valueObj);
}
}
throw new ArgumentException(" ### -> public static KeyValuePair<object , object > CastFrom(Object obj) : Error : obj argument must be KeyValuePair<,>");
}
From the OP:
Instead of converting my whole Dictionary, i decided to keep my obj
dynamic the whole time. When i access the keys and values of my
Dictionary with a foreach later, i use foreach(dynamic key in
obj.Keys) and convert the keys and values to strings simply.
Another option is to use NewtonSoft.JSON.
var dictionary = JObject.FromObject(anObject).ToObject<Dictionary<string, object>>();
If you don't mind LINQ Expressions;
public static Dictionary<string, object> ConvertFromObjectToDictionary(object arg)
{
return arg.GetType().GetProperties().ToDictionary(property => property.Name, property => property.GetValue(arg));
}
this should work:
for numbers, strings, date, etc.:
public static void MyMethod(object obj)
{
if (typeof(IDictionary).IsAssignableFrom(obj.GetType()))
{
IDictionary idict = (IDictionary)obj;
Dictionary<string, string> newDict = new Dictionary<string, string>();
foreach (object key in idict.Keys)
{
newDict.Add(key.ToString(), idict[key].ToString());
}
}
else
{
// My object is not a dictionary
}
}
if your dictionary also contains some other objects:
public static void MyMethod(object obj)
{
if (typeof(IDictionary).IsAssignableFrom(obj.GetType()))
{
IDictionary idict = (IDictionary)obj;
Dictionary<string, string> newDict = new Dictionary<string, string>();
foreach (object key in idict.Keys)
{
newDict.Add(objToString(key), objToString(idict[key]));
}
}
else
{
// My object is not a dictionary
}
}
private static string objToString(object obj)
{
string str = "";
if (obj.GetType().FullName == "System.String")
{
str = (string)obj;
}
else if (obj.GetType().FullName == "test.Testclass")
{
TestClass c = (TestClass)obj;
str = c.Info;
}
return str;
}
public static void MyMethod(object obj){
Dictionary<string, string> dicEditdata = data as Dictionary<string, string>;
string abc=dicEditdata["id"].ToString();}
suppose---
if you place the cursor over the object(obj) while debugging and
if you get an object with the value {['id':'ID1003']}
then you can use the value as
string abc=dicEditdata["id"].ToString();
Assuming key can only be a string but value can be anything try this
public static Dictionary<TKey, TValue> MyMethod<TKey, TValue>(object obj)
{
if (obj is Dictionary<TKey, TValue> stringDictionary)
{
return stringDictionary;
}
if (obj is IDictionary baseDictionary)
{
var dictionary = new Dictionary<TKey, TValue>();
foreach (DictionaryEntry keyValue in baseDictionary)
{
if (!(keyValue.Value is TValue))
{
// value is not TKey. perhaps throw an exception
return null;
}
if (!(keyValue.Key is TKey))
{
// value is not TValue. perhaps throw an exception
return null;
}
dictionary.Add((TKey)keyValue.Key, (TValue)keyValue.Value);
}
return dictionary;
}
// object is not a dictionary. perhaps throw an exception
return null;
}
I've done something like this and works for me.
using System.ComponentModel;
var dictionary = new Dictionary<string, string>();
foreach (var propDesc in TypeDescriptor.GetProperties(Obj))
{
if (!string.IsNullOrEmpty(propDesc.GetValue(Obj)))
{
dictionary.Add(propDesc.Name, propDesc.GetValue(Obj));
}
}
Also, another alternative and innovative solution is here.
var dictionary = new System.Web.Routing.RouteValueDictionary(Obj);
I hope this could work :)
// obj = new { a = "string", b = 0, c = true };
static Dictionary<string, object> ToDictionary(object obj)
{
int i = 0;
var props = obj.GetType().GetProperties();
return props.ToDictionary(k => props[i].Name, v => props[i++].GetValue(obj));
}
This code securely works to convert Object to Dictionary (having as premise that the source object comes from a Dictionary):
private static Dictionary<TKey, TValue> ObjectToDictionary<TKey, TValue>(object source)
{
Dictionary<TKey, TValue> result = new Dictionary<TKey, TValue>();
TKey[] keys = { };
TValue[] values = { };
bool outLoopingKeys = false, outLoopingValues = false;
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))
{
object value = property.GetValue(source);
if (value is Dictionary<TKey, TValue>.KeyCollection)
{
keys = ((Dictionary<TKey, TValue>.KeyCollection)value).ToArray();
outLoopingKeys = true;
}
if (value is Dictionary<TKey, TValue>.ValueCollection)
{
values = ((Dictionary<TKey, TValue>.ValueCollection)value).ToArray();
outLoopingValues = true;
}
if(outLoopingKeys & outLoopingValues)
{
break;
}
}
for (int i = 0; i < keys.Length; i++)
{
result.Add(keys[i], values[i]);
}
return result;
}
This way for object array to Dictionary<string, object> List coverting
object[] a = new object[2];
var x = a.Select(f => (Dictionary<string, object>)f).ToList();
This way for single object to Dictionary<string, object> coverting
object a = new object;
var x = (Dictionary<string, object>)a;
You can create a generic extension method and then use it on the object like:
public static class Extensions
{
public static KeyValuePair<TKey, TValue> ToKeyValuePair<TKey, TValue>(this Object obj)
{
// if obj is null throws exception
Contract.Requires(obj != null);
// gets the type of the obj parameter
var type = obj.GetType();
// checks if obj is of type KeyValuePair
if (type.IsGenericType && type == typeof(KeyValuePair<TKey, TValue>))
{
return new KeyValuePair<TKey, TValue>(
(TKey)type.GetProperty("Key").GetValue(obj, null),
(TValue)type.GetProperty("Value").GetValue(obj, null)
);
}
// if obj type does not match KeyValuePair throw exception
throw new ArgumentException($"obj argument must be of type KeyValuePair<{typeof(TKey).FullName},{typeof(TValue).FullName}>");
}
and usage would be like:
KeyValuePair<string,long> kvp = obj.ToKeyValuePair<string,long>();
I use this simple method:
public Dictionary<string, string> objToDict(XYZ.ObjectCollection objs) {
var dict = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> each in objs){
dict.Add(each.Key, each.Value);
}
return dict;
}
You can use this:
Dictionary<object,object> mydic = ((IEnumerable)obj).Cast<object>().ToList().ToDictionary(px => px.GetType().GetProperty("Key").GetValue(px), pv => pv.GetType().GetProperty("Value").GetValue(pv));
string BaseUrl = "http://www.example.com";
HttpClient client = new HttpClient { BaseAddress = new Uri(BaseUrl) };
PropertyInfo[] properties = object.GetType().GetProperties();
Dictionary<string, string> dictionary = new Dictionary<string, string>();
foreach (PropertyInfo property in properties)
{
dictionary.Add(property.Name, property.GetValue(model, null).ToString());
}
foreach (string key in dictionary.Keys)
{
client.DefaultRequestHeaders.Add(key, dictionary[key]);
}
As I understand it, you're not sure what the keys and values are, but you want to convert them into strings?
Maybe this can work:
public static void MyMethod(object obj)
{
var iDict = obj as IDictionary;
if (iDict != null)
{
var dictStrStr = iDict.Cast<DictionaryEntry>()
.ToDictionary(de => de.Key.ToString(), de => de.Value.ToString());
// use your dictStrStr
}
else
{
// My object is not an IDictionary
}
}
object parsedData = se.Deserialize(reader);
System.Collections.IEnumerable stksEnum = parsedData as System.Collections.IEnumerable;
then will be able to enumerate it!
Simple way:
public IDictionary<T, V> toDictionary<T, V>(Object objAttached)
{
var dicCurrent = new Dictionary<T, V>();
foreach (DictionaryEntry dicData in (objAttached as IDictionary))
{
dicCurrent.Add((T)dicData.Key, (V)dicData.Value);
}
return dicCurrent;
}

How to handle a generic dictionary whose types are unknown and don't matter?

If 'value' is an incoming generic dictionary whose types are unknown/don't matter, how do I take its entries and put them into a target dictionary of type IDictionary<object, object> ?
if(type == typeof(IDictionary<,>))
{
// this doesn't compile
// value is passed into the method as object and must be cast
IDictionary<,> sourceDictionary = (IDictionary<,>)value;
IDictionary<object,object> targetDictionary = new Dictionary<object,object>();
// this doesn't compile
foreach (KeyValuePair<,> sourcePair in sourceDictionary)
{
targetDictionary.Insert(sourcePair.Key, sourcePair.Value);
}
return targetDictionary;
}
EDIT:
Thanks for the responses so far.
The problem here is that the argument to Copy is only known as type 'object'. For example:
public void CopyCaller(object obj)
{
if(obj.GetType() == typeof(IDictionary<,>)
Copy(dictObj); // this doesn't compile
}
Make your method generic as well and then you'll be able to do what you're doing. You won't have to change your usage pattern since the compiler will be able to infer generic types from input types.
public IDictionary<object, object> Copy(IDictionary<TKey, TValue> source)
{
IDictionary<object,object> targetDictionary = new Dictionary<object,object>();
foreach (KeyValuePair<TKey, TValue> sourcePair in sourceDictionary)
{
targetDictionary.Insert(sourcePair.Key, sourcePair.Value);
}
return targetDictionary;
}
If you don't really need to convert it from IDictionary<TKey, TValue> to IDictionary<object, object> then you can use the copy constuctor of Dictionary<TKey, TValue> which accepts another dictionary as input and copies all values--just like you're doing now.
You can exploit the fact that generic dictionaries implement the IDictionary interface.
public static Dictionary<object, object> CreateCopy(IDictionary source)
{
var copy = new Dictionary<object, object>(source.Count);
foreach (DictionaryEntry entry in source)
{
copy.Add(entry.Key, entry.Value);
}
return copy;
}
Usage example:
var source = new Dictionary<int, string>() { { 1, "Foo" }, { 2, "Bar" }, };
var copy = CreateCopy(source);
Console.WriteLine(String.Join(", ", copy.Values));
Output:
Foo, Bar
Here is a method (don't leave it as static, unless you need it to be, I wrote it in a quick console app) that basically converts a Dictionary of any type to an object/object dictionary.
private static Dictionary<object,object> DeTypeDictionary<T,U>(Dictionary<T,U> inputDictionary)
{
Dictionary<object, object> returnDictionary = new Dictionary<object, object>();
foreach(T key in inputDictionary.Keys)
{
if( (key is object) && (inputDictionary[key] is object))
{
returnDictionary.Add(key, inputDictionary[key]);
}
else
{
//sorry these aren't objects. they may be dynamics.
continue;
}
}
return returnDictionary;
}
...and here is how you use it...
Dictionary<string, DateTime> d = new Dictionary<string, DateTime>();
d.Add("rsgfdg", DateTime.Now);
d.Add("gfdsgd", DateTime.Now);
Dictionary<object, object> newDictionary = DeTypeDictionary<string, DateTime>(d);
So you have an object that may be a Dictionary and you want to:
Test it's a dictionary
Act on it appropriately if it is
Let's start with a generic function that does what you want if you knew the type arguments:
class Bar
{
public static void Foo<TKey, TValue>(Dictionary<TKey, TValue> input) { ... }
}
Now we'll just have to do some reflection
bool TryHandleDictionary(object o)
{
var t = o.GetType();
if (!t.IsGenericType || t.GetGenericTypeDefinition() != typeof(Dictionary<,>)) return false;
var m = typeof(Bar).GetMethod("Foo", BindingFlags.Public | BindingFlags.Static);
var m1 = m.MakeGenericMethod(t.GetGenericArguments());
m1.Invoke(null, new[] { o });
return true;
}
This may be a fix for you but you'll need .net 3.5 or greater to use the var keyword.
// this should compile
foreach (var sourcePair in sourceDictionary)
{
targetDictionary.Insert(sourcePair.Key, sourcePair.Value);
}

Categories

Resources