如何在C#中将动态对象转换为Dictionary<TKey, TValue>
我该怎么办?
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
}
}
答案 0 :(得分:38)
我使用这个助手:
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.");
}
}
用法只是在对象上调用.ToDictionary()
希望它有所帮助。
答案 1 :(得分:34)
以上答案都很酷。我发现json序列化对象很容易并反序列化为字典。
public static Dictionary<string, TValue> ToDictionary<TValue>(object obj)
{
var json = JsonConvert.SerializeObject(obj);
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, TValue>>(json);
return dictionary;
}
我不知道性能是如何影响的,但这更容易阅读。你也可以将它包装在一个函数中。
var obj = new { foo = 12345, boo = true };
var dictionary = ToDictionary<string>(obj);
像这样使用:
server{
listen 443 ssl;
server_name dom1.com;
location / {
proxy_pass https://dom2.com$request_uri? permanent;
}
location /api/auth/ {
proxy_pass https://dom1.com
}
}
答案 2 :(得分:17)
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<,>");
}
来自OP:
而不是转换我的整个词典,我决定保留我的obj 一直充满活力。当我访问我的键和值 字典与foreach后,我使用foreach(动态键在 obj.Keys)并简单地将键和值转换为字符串。
答案 3 :(得分:4)
这应该有效:
表示数字,字符串,日期等:
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
}
}
如果您的词典还包含其他一些对象:
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;
}
答案 4 :(得分:3)
假设key只能是一个字符串,但值可以是任何东西试试这个
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;
}
答案 5 :(得分:3)
public static void MyMethod(object obj){
Dictionary<string, string> dicEditdata = data as Dictionary<string, string>;
string abc=dicEditdata["id"].ToString();}
假设---
如果在调试时将光标放在对象(obj)上
如果你得到一个值为{['id':'ID1003']}
的对象
然后你可以使用值
string abc=dicEditdata["id"].ToString();
答案 6 :(得分:3)
另一种选择是使用NewtonSoft.JSON。
var dictionary = JObject.FromObject(anObject).ToObject<Dictionary<string, object>>();
答案 7 :(得分:1)
此代码可以安全地将Object转换为Dictionary(前提是源对象来自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;
}
答案 8 :(得分:1)
如果您打算使用LINQ表达式;
public static Dictionary<string, object> ConvertFromObjectToDictionary(object arg)
{
return arg.GetType().GetProperties().ToDictionary(property => property.Name, property => property.GetValue(arg));
}
答案 9 :(得分:1)
我做过这样的事情并且对我有用。
<块引用>使用 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));
}
}
此外,另一种替代的创新解决方案是 here。
var dictionary = new System.Web.Routing.RouteValueDictionary(Obj);
答案 10 :(得分:0)
您可以创建一个通用扩展方法,然后在对象上使用它,如:
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}>");
}
并且用法如下:
KeyValuePair<string,long> kvp = obj.ToKeyValuePair<string,long>();
答案 11 :(得分:0)
我使用这个简单的方法:
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;
}
答案 12 :(得分:0)
您可以使用此:
Dictionary<object,object> mydic = ((IEnumerable)obj).Cast<object>().ToList().ToDictionary(px => px.GetType().GetProperty("Key").GetValue(px), pv => pv.GetType().GetProperty("Value").GetValue(pv));
答案 13 :(得分:-1)
据我了解,您不确定键和值是什么,但是您想将它们转换为字符串?
也许这可行:
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
}
}
答案 14 :(得分:-1)
object parsedData = se.Deserialize(reader);
System.Collections.IEnumerable stksEnum = parsedData as System.Collections.IEnumerable;
然后将能够枚举它!
答案 15 :(得分:-1)
简单方法:
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;
}