从字典值中获取列表

时间:2015-02-09 22:44:10

标签: c# json dictionary

我有一个字典,是在我根据类反序列化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对象并进行反序列化时,经过一些处理后,我最终得到了我的字典。

我可以获得非List&lt;串GT;价值很容易,但无法获得列表。

我试过了

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]);

1 个答案:

答案 0 :(得分:0)

您是说您的词典属于dictionary<string,MyClass>类型?

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

fi = myDict["myKey"].valList;

顺便说一句,在声明它时不要初始化fi,因为你在声明过程中创建的列表只会被垃圾收集。

或者:

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

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

编辑: 不幸的是,我在这里以及Xamarin Developers Facebook小组的帖子中传播了这个。我会尽量保留相关细节以供参考。

解决方案过于复杂,因为您尝试使用Reflection在通用代码段内完成所有操作。

相反,我建议你定义一个界面:

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属性实现,但是没有使用Reflection的话,性能会得到改善,并且你有更好的封装(例如,你不依赖于命名约定)列表属性)。

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

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