将字典转换为 c# 对象

Posted

技术标签:

【中文标题】将字典转换为 c# 对象【英文标题】:Convert Dictionary to c# object 【发布时间】:2021-06-06 16:06:41 【问题描述】:

我有一个嵌套字典对象输出,如下所示


"name":"test",
"id":1,
"parent": 
      "name":"test1",
      "id":2,
      "parent":
           "name":"test2",
           "id":3,
            "parent":
                "name":"test3",
                "id":4,
                "parent":
                    ....
                      
                
            
      

这里是返回字典对象的代码:

class GetData

    public HttpWebResponse WebResponse  get; private set; 
    public Dictionary<string, object> Data  get; private set; 

    public GetData(HttpWebResponse webResponse, Dictionary<string, object> data)
    
        WebResponse = webResponse;
        Data = data;
    

我有一个包含上述响应的对象,如下所示:

var responseData = GetResponseData(req);

现在我想将上面的字典对象转换为 c# 对象。以下是我的c#对象

class SomeClass

    public int Id  get; 
    public string Name  get; 
    public SomeClass Parent  get; 
    
    public IEnumerable<SomeClass> GetAncestry()
    
        if (Parent is not null)
        
            yield return Parent;
            foreach (var ancestor in Parent.GetAncestry()) yield return ancestor;
        
    

我正在尝试以下方法将我的字典对象转换为“SomeClass”对象,但它对我不起作用。有人可以帮我解决吗?

List<SomeClass> smClass = new List<SomeClass>(responseData .Values);

【问题讨论】:

GetData 是类的可怕名称 您发布的是 JSON 字符串,而不是字典。您发布的内容不执行任何类型的 JSON 解析。 GetData 类不返回任何内容,它只是将构造函数参数公开为属性。 你为什么使用 Object 的字典而不是类型化的字典。听起来你对架构有误解,你应该描述你正在尝试做的事情,而不是你想要的解决方案 将我的字典对象转换为SomeClass对象 为什么要创建一个列表然后List&lt;SomeClass&gt;(responseData .Values) 你试过反序列化这个 JSON 字符串吗?例如JsonConvert.DeserializeObject&lt;SomeClass&gt;(json)。不需要GetData 类或Dictionary&lt;string,object&gt; 【参考方案1】:

尝试创建结构(或类),例如:

public class NamedObject

    int id get; set;
    string name get; set;
    NamedObject parent get; set;

然后你可以通过Newtonsoft.Json.JsonConvert.DeserializeObject反序列化你的json(你需要Newtonsoft.Json库或者NuGet包)

NamedObject namedObject = JsonConvert.DeserializeObject<NamedObject>(json);

工作示例(来自您之前的 question):

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;

namespace ConsoleApp1

    internal class Program
    

        private static void Main(string[] args)
        
            Console.WriteLine("Hello World!");

            string s = " \"name\":\"test\", \"id\":1, \"parent\":  \"name\":\"test1\", \"id\":2, \"parent\": \"name\":\"test2\", \"id\":3, \"parent\": \"name\":\"test3\", \"id\":4, \"parent\": null    ";
            TreeNode node = JsonConvert.DeserializeObject<TreeNode>(s);
        
    

    public class TreeNode
    
        [JsonProperty("name")]
        public string Name  get; set; 
        [JsonProperty("id")]
        public int ID  get; set; 
        public NodeType Type  get; 
        public Dictionary<TreeNode, NodeType> Childern  get; 
        public TreeNode GetChildernByName(string name) => Childern.First(x => x.Key.Name == name).Key;
        [JsonProperty("parent")]
        public TreeNode Parent  get; private set; 
        public string FullName => IsRoot ? string.Empty : this.Parent.FullName + "/" + Name;
        public TreeNode(string name, NodeType type, TreeNode parent)
        
            this.Name = name;
            this.Type = type;
            this.Parent = parent;
            this.Childern = new Dictionary<TreeNode, NodeType>();
        
        public TreeNode()
        

        
        public TreeNode(string name) : this(name, NodeType.Folder, null)  
        public TreeNode(string name, NodeType type) : this(name, type, null)  
        public bool IsRoot => Parent == null;
        public void AddChild(params TreeNode[] nodes) => AddChild(true, nodes);
        public void AddChild(bool setParent, params TreeNode[] nodes)
        
            foreach (TreeNode node in nodes)
            
                Childern.Add(node, node.Type);
                if (setParent) node.Parent = this;
            
        
        public IEnumerable<TreeNode> GetFullPath()
        
            List<TreeNode> parents = new List<TreeNode>();
            if (this.Parent != null)
            
                parents.AddRange(Parent.GetFullPath());
            
            parents.Add(this);
            return parents;
        
        public override string ToString() => Name;
    
    public enum NodeType
    
        Folder,
        File
    

您可以为公共字段使用与 json 中相同的名称,也可以在需要的地方设置 JsonProperty 属性。只记得,你必须有没有参数的构造函数,我建议使用可为空的类型(例如 int?)

【讨论】:

公共字段不是属性。属性是类接口的一部分,字段总是被视为实现细节,无论是否公开 @PanagiotisKanavos 谢谢,我错过了。已更正。 你也不需要JsonProperty,JSON.NET默认使用camel-case 也只是一个快速观察,NamedObject namedObject = JsonConvert.DeserializeObject(json); 应该是 NamedObject namedObject = JsonConvert.DeserializeObject&lt;NamedObject&gt;(json); @PanagiotisKanavos,这对我来说是新观点,我只在一个项目中使用 json 并且我有驼峰式名称,所以我从不详细处理这个问题。我只知道名称不匹配时有 JsonProperty。

以上是关于将字典转换为 c# 对象的主要内容,如果未能解决你的问题,请参考以下文章

将表转换为像字典一样的 json 对象 SQL?

JavaScript 中的 C# 字典等效项

将 JSON 转换为字典?

将 DataTable 转换为字典 C#

C# 将字典转换为类似字符串的 CSV

在 C# 中转换为泛型类型