仅针对 c# 中的一个键循环遍历 Dictionary<string, object>

Loop trought Dictionary<string, object> only for a key in c#

我有一个字符串和对象的字典,我通过反序列化得到了这个 json 答案:

{"labels":[{"id":"1","descrizione":"Etichetta interna","tipo":"0","template_file":"et_int.txt"},{"id":"2","descrizione":"Etichetta esterna","tipo":"1","template_file":"et_ext.txt"}],"0":200,"error":false,"status":200}

使用代码:

var labels = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);   

现在我只想循环遍历 "labels" 键内的对象。 我试过了

foreach (var outer in labels["labels"]){/* code */}

但我得到错误:

CS1579: foreach statement cannot operate on variables of type 'object' because 'object' does not contain a public definition for 'GetEnumerator'.

解决了用 class 替换字典的问题,谢谢

您需要遍历字典。

    foreach(KeyValuePair<string, Object> entry in labels)
     {
          // do something with entry.Value or entry.Key
     }

一旦开始遍历它,您就可以访问键和值。由于您有兴趣查看 entry.value,因此您可以轻松地对其进行操作。目前你的字典值是没有枚举数的对象类型

可能的解决方案:

static void Main(string[] args) {

    string json = @"{'labels':[{'id':'1','descrizione':'Etichetta interna','tipo':'0','template_file':'et_int.txt'},{'id':'2','descrizione':'Etichetta esterna','tipo':'1','template_file':'et_ext.txt'}],'0':200,'error':false,'status':200}";
    var labels = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
    IEnumerable inner_labels = labels["labels"] as IEnumerable;
    if (inner_labels != null) {
        foreach (var outer in inner_labels) { 
            Console.WriteLine(outer);
        }
    }

}

否则,您可以创建一个带有反序列化信息的 class 并指示反序列化器将您的 json 字符串反序列化为该类型:

using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Xml.Serialization;

[Serializable]
public class JsonData {

    [XmlElement("labels")]
    public List<JsonLabel> labels { get; set; }

    [XmlElement("0")]
    public int zero { get; set; }

    [XmlElement("error")]
    public bool error { get; set; }

    [XmlElement("status")]
    public int status { get; set; }


}

[Serializable]
public class JsonLabel {
    [XmlElement("id")]
    public int id { get; set; }

    [XmlElement("descrizione")]
    public string descrizione { get; set; }

    [XmlElement("tipo")]
    public int tipo { get; set; }

    [XmlElement("template_file")]
    public string template_file { get; set; }

}

class Program {


    static void Main(string[] args) {
        string json = @"your json string here...";
        var jsonData = new JavaScriptSerializer().Deserialize<JsonData>(json);
        foreach (var label in jsonData.labels) {
            Console.WriteLine(label.id);
        }
    }

}

您的问题是您将每个字典条目的 ValueType 定义为 object。 C# 不知道如何遍历对象。因此,一旦 JavaScriptSerializer 解析了 JSON,您就需要弄清楚对象内部实际是什么类型。一种方法是

var t = typeof(labels["labels"]);

一旦您知道序列化程序正在创建什么类型,您需要做的就是将对象转换回该类型。例如,假设它是一个对象列表

var labels = (List<object>)labels["labels"];
foreach (var label in labels)
{
}

或者,如果 JSON 中的每个对象都相同,您可以尝试创建您需要的类型的字典。所以你序列化变成

var labels = new JavaScriptSerializer()
                 .Deserialize<Dictionary<string, List<object>>>(json); 

创建一个 class 来反序列化您的 json:

要创建 classes,您可以将 json 复制到剪贴板并使用

编辑/选择性粘贴/粘贴JSON为class

在visual studio(我用的是vs2013)。

    [TestMethod]
    public void test()
    {
        string json = "{\"labels\" : [{\"id\" : \"1\",\"descrizione\" : \"Etichetta interna\",\"tipo\" : \"0\",\"template_file\" : \"et_int.txt\"}, {\"id\" : \"2\",\"descrizione\" : \"Etichetta esterna\",\"tipo\" : \"1\",\"template_file\" : \"et_ext.txt\"}],\"0\" : 200,\"error\" : false,\"status\" : 200}";
        var root = JsonConvert.DeserializeObject<Rootobject>(json);

        foreach (var label in root.Labels)
        {
            //Use label.Id, label.Descrizione, label.Tipo, label.TemplateFile
        }
    }

    public class Rootobject
    {
        public Label[] Labels { get; set; }
        public int _0 { get; set; }
        public bool Error { get; set; }
        public int Status { get; set; }
    }

    public class Label
    {
        public string Id { get; set; }
        public string Descrizione { get; set; }
        public string Tipo { get; set; }
        public string TemplateFile { get; set; }
    }

你能试试下面的代码片段吗? 说不定对你有帮助。

foreach (var item in labels["labels"] as ArrayList)
        {
            Console.Write(item);
        }