【问题标题】:Getting a list from a dictionary value从字典值中获取列表
【发布时间】:2015-02-09 22:44:10
【问题描述】:

我有一个字典,它是在我反序列化基于类的 JSON 对象时创建的。

例如,我的班级是这样的

public MyClass
{
    public string someString {get;set;}
    public double someDouble {get;set;}
    public bool someBool {get;set;}
    public List<string> valList {get;set;}
    public List<string> valList2 {get;set;}
}

当使用 JSON.NET 读回 JSON 对象并对其进行反序列化时,经过一些处理后,我最终得到了我的字典。

我可以很容易地获得非列表 值,但无法获得列表。

我试过了

var fi = new List<string>(){};
fi = myDict["myKey"] as List<string>;

fi = myDict["myKey"]

但两者都没有编译

有没有办法从字典中提取我的列表?

反序列化就是这样完成的

public static T DeserialiseEventData<T>(this T obj, string serialisedData)
    {
        try
        {
            return (T)JsonConvert.DeserializeObject(serialisedData, typeof(T));
        }
        catch
        {
            return default(T);
        }
    }

对于字典,我首先使用方法 1 创建键(字符串),然后使用 vals = GetValuesFromClass(cts); 调用以下方法

 private static List<string> GetValuesFromClass<T>(T obj)
    {
        var rv = new List<string>();
        if (obj == null)
            return rv;
        var type = obj.GetType();
        var t = type.GetProperties();
        if (t.Length > 0)
        {
            for (var i = 0; i < t.Length; ++i)
            {
                if (t[i].ToString().Contains("List"))
                {
                    var lstProperty = t[i].Name;
                    var res = obj.GetType().GetProperty(lstProperty).GetValue(obj, null) as List<string>;
                    Console.WriteLine(lstProperty);
                    if (res != null)
                    {
                        if (res.Count == 0)
                            rv.AddRange(new List<string>(){ string.Empty });
                        else
                            rv.AddRange(res);
                    }
                    else
                    {
                        rv.AddRange(new List<string>(){ string.Empty });
                    }
                }
                else
                {
                    var test = t[i].GetValue(obj, null);
                    if (test == null)
                        rv.Add(string.Empty);
                    else
                        rv.Add(test.ToString());
                }
            }
        }
        return rv;
    }

返回时,我会这样做

for (var i = 0; i < translate.Count; ++i)
     rvDict.Add(keys, vals[i]);

【问题讨论】:

  • 您能否添加一个 json 输入样本(小 sn-p)以及将其序列化到该类中的端点方法?
  • 由于您既没有显示json也没有显示字典声明,因此任何人都无法回答这个问题。你也没有告诉我们编译错误是什么。
  • 如果您声明了 dictionary&lt;string,string&gt;,例如,您可以将字典对象转换为 Listvar fi = YourDictionary.Keys.ToList();
  • 我已经扩展了这个问题,希望能有所帮助

标签: c# json dictionary


【解决方案1】:

你是说你的字典是dictionary&lt;string,MyClass&gt;类型的吗?

如果是这样,myDict["myKey"] 将返回 MyClass 的一个实例。因此,如果您想要这些列表,则需要明确引用它们:

fi = myDict["myKey"].valList;

顺便说一下,声明 fi 时不要初始化它,因为你在声明期间创建的列表只会被垃圾回收。

要么:

var fi = myDict["myKey"].valList;

List<string> fi;
fi = myDict["myKey"].valList;

编辑: 不幸的是,我在这里和 Xamarin 开发人员 Facebook 组中将其传播到您的帖子中。我会尽量保留相关细节以供参考。

解决方案过于复杂,因为您试图在使用反射的通用代码段内完成所有工作。

相反,我建议您定义一个接口:

public interface IValuesSource
{
    List<string> Values { get; }
}

然后,在您的每个类上(因为您之前提到它们是您的类),实现 IValuesSource:

public MyClass : IValuesSource
{
    public string someString {get;set;}
    public double someDouble {get;set;}
    public bool someBool {get;set;}
    public List<string> valList {get;set;}
    public List<string> valList2 {get;set;}

    public List<string> Values
    {
        get
        {
            var values = new List<string>();

            values.Add(someString);
            values.Add(someDouble.ToString());
            values.Add(someBool.ToString());
            values.AddRange(valList);
            values.AddRange(valList2);

            return values;
        }
    }
}

您的每个反序列化类都有自己独特的 Values 属性实现,但反射不会搞砸,性能会得到改善,并且您有更好的封装(例如,您不依赖于命名约定列出属性)。

然后,只要您确保通过此接口引用对象:

IValuesSource cts;
  ....
vals = cts.Values;

【讨论】:

    猜你喜欢
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多