2015-02-09 2 views
-3

У меня есть словарь, который создается, когда я десериализую объект 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 считывается при помощи Json.NET и deserialised, я в конечном итоге с моим словарем после немного обработки.

Я могу получить строку non-List <> значения достаточно легко, но не могу получить списки.

Я попытался

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

вы можете добавить образец ввода JSon (небольшой фрагмент) и метод конечных точек seralizes его в этом классе? – Prescott

+2

Поскольку вы не указали ни слова json, ни словаря, никто не может ответить на этот вопрос. Вы также не сообщили нам, что такое ошибка компиляции. –

+0

, если у вас есть 'словарь <строка, строка>', объявленный, например, вы можете просто преобразовать объект словаря в список 'var fi = YourDictionary.Keys.ToList();' – MethodMan

ответ

0

Вы говорите, что ваше диктофон nary имеет тип dictionary<string,MyClass>?

Если это так, myDict ["myKey"] вернет экземпляр MyClass. Так что если вы хотите, списки, вы будете нуждаться, чтобы ссылаться на них в явном виде:

fi = myDict["myKey"].valList; 

Кстати, не инициализируется Fi, когда вы объявляете его, как список вы создаете во время декларации будет просто сбор мусора.

Либо:

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

или

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

EDIT: К сожалению, я распространять это через ваши посты здесь и на группе Xamarin разработчиков 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; 
Смежные вопросы