将动态类型转换为字典C#

33

我有一个动态对象,长这样:

 {
    "2" : "foo",
    "5" : "bar",
    "8" : "foobar"
 }

我怎样才能将它转换成一个字典


2
这看起来像是JSON。您是否正在寻找将JSON反序列化为Dictionary<K,V>的方法? - Ondrej Tucny
1
你可以使用 Linq Group 方法。请看这里:http://code.msdn.microsoft.com/LINQ-to-DataSets-Grouping-c62703ea - mike00
它是什么对象?JSON字符串?还是JSON对象?或者是KeyValuePair列表?还是其他什么东西? - Avishek
@OndrejTucny 实际上这是一个JSON反序列化的产物。操作方法如下:Dictionary<string, dynamic> values = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json) 问题中的“json”是被塞进字典中的值。 - Kristian Nissen
9个回答

50

您可以使用反射填充字典:

public Dictionary<String, Object> Dyn2Dict(dynamic dynObj)
{
     var dictionary = new Dictionary<string, object>();
     foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(dynObj))
     {
        object obj = propertyDescriptor.GetValue(dynObj);
        dictionary.Add(propertyDescriptor.Name, obj);
     }
     return dictionary;
}

由于它未标记为最佳答案,因此我认为应该将其置于上方。这样可以为开发人员提供更多的可能性。 - Pomme De Terre
1
如果动态对象是ExpandoObject,则无法工作。 - OKEEngine

43
你可以使用RouteValueDictionary将C#对象转换为字典。请参阅:RouteValueDictionary类-MSDN。它将object属性转换为键值对。
像这样使用它:
var toBeConverted = new {
    foo = 2,
    bar = 5,
    foobar = 8
};

var result = new RouteValueDictionary(toBeConverted);

9
巧妙地重新利用现有的类! - Dexter Legaspi

23

如果你在评论中提到的动态值是通过Json.Net反序列化创建的,那么它应该是一个JObject。原来JObject已经实现了IDictionary<string, JToken>,所以你可以直接将其作为字典使用,无需进行任何转换,如下所示:

string json = 
     @"{ ""blah"" : { ""2"" : ""foo"", ""5"" : ""bar"", ""8"" : ""foobar"" } }";

var dict = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json);
dynamic dyn = dict["blah"];

Console.WriteLine(dyn.GetType().FullName);     // Newtonsoft.Json.Linq.JObject
Console.WriteLine(dyn["2"].ToString());        // foo

如果您宁愿使用 Dictionary<string, string>,那么可以像这样进行转换:

Dictionary<string, string> newDict = 
          ((IEnumerable<KeyValuePair<string, JToken>>)dyn)
                     .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToString());

14
你可以使用Json.Net将其反序列化为字典。
string json = dynamicObject.ToString(); // suppose `dynamicObject` is your input
Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);

4
好的,但是string json = dynamicObject.ToString()没有成功。你需要使用string json = JsonConvert.SerializeObject(dynamicObject); - derloopkat

4
与EMA答案非常相似,但使用一行LINQ魔法:

Dictionary<string, object> myDict = sourceObject.GetType().GetProperties().ToDictionary(prop => prop.Name, prop => prop.GetValue(sourceObject, null));

3

System.Web.Helpers 在 .NET 4.5 中未被包含。 - nawfal

0
你可以使用jsonSerializer来实现,需要引用System.Net.Extensions。以下是示例代码。
var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<Dictionary<string,string>>(jsonText);
var place = dict["8"]; // "foobar"

0

如果你在这里使用 dynamic 实现:

https://github.com/b9chris/GracefulDynamicDictionary

你可以直接从实现中获取字典。使用上述实现(为回答另一个SO问题而编写)的一个优点是,你可以轻松地在特定实现和动态之间进行切换,如下所示:

    dynamic headers = new DDict();
    headers.Authorization = token;
    if (doesNeedSiteId)
        headers.SiteId = siteId;
    
    await post(headers);
}

protected async Task post(DDict headers)
{
    var dict = headers.GetDictionary(); // Dictionary<string, object>

在上面的代码中,头部集合被方便地创建为一个dynamic对象,但是其具体实现是DDict,而且即使你声明为dynamic并使用其特性,post()方法也可以接受它。

0
一行代码解决将您的JSON文本转换为字典的问题:
IDictionary<string, object> dict = new JavaScriptSerializer().Deserialize<IDictionary<string, object>>(json);

那么

if (dict.ContainsKey("field1"))
   string field1value = dict["field1"];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接