Как читать свойства анонимных типов с помощью динамической переменной

У меня появилась хитрая идея использовать динамическую переменную для проверки результатов метода, который возвращает анонимный тип — точнее, он возвращает JsonResult, который в json выглядит так

{ "newData" : [ 1120741.2697475906,
      826527.64681837813
    ],
  "oldData" : [ 1849870.2326665826,
      1763440.5884212805
    ],
  "timeSteps" : [ 0,
      4.8828124999999998e-10
    ],
  "total" : 2
}

Я могу прочитать JSonResult, который даст мне анонимный тип. Вот мой код:

var jsonResult = controller.GetChangeData(1) as JsonResult;
dynamic data = jsonResult.Data;
Assert.AreEqual(2, data.total); // This works fine :)

Но как мне получить, например, «newData»? Этот код....

var newData = data.newData;

Дает мне System.Linq.Enumerable.WhereSelectArrayIterator, но я не знаю, что с ним делать, чтобы иметь возможность просто использовать его как массив двойников.

Я попытался использовать его как двойное [], но это тоже не работает.

Кроме того, могу ли я легко проверить, определено ли свойство в динамике?


person Matt Roberts    schedule 12.11.2010    source источник
comment
Что произойдет, если вы попробуете это data.newData.ToArray()?   -  person Pieter van Ginkel    schedule 12.11.2010
comment
var data2 = data.newData.ToArray(); --- › 'object' не содержит определения для 'ToArray' (также пробовали с некоторыми приведениями)   -  person Matt Roberts    schedule 12.11.2010


Ответы (3)


Причина, по которой .ToArray() не работает, заключается в том, что это метод расширения, а методы расширения недоступны во время выполнения. Это просто означает, что вы должны вызывать функцию статически. Enumerable.ToArray<double>(data.newData) работает?

Вам может понадобиться Enumerable.ToArray(Enumerable.Cast<double>(data.newData)) в зависимости от того, какие элементы newData на самом деле есть.

person Gabe    schedule 12.11.2010
comment
Да! Enumerable.ToArray‹double›(data.newData) делает всю работу за меня :) Спасибо - person Matt Roberts; 12.11.2010

Чтобы получить свойства экземпляра динамического типа

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(dyn);
foreach (PropertyDescriptor prop in props)
{
  object val = prop.GetValue(dyn);
  var propName = prop.Name;
  var propValue = val;
}

где dyn — экземпляр динамического объекта.

person Shiv Kumar    schedule 12.11.2010
comment
Это был полезный фрагмент кода для копирования и вставки, который, я уверен, станет методом расширения на работе... - person Bryan Boettcher; 22.05.2012

Не могли бы вы использовать класс JavaScriptSerializer для преобразования строки Json в динамическую переменную? Например:

var serializer = new JavaScriptSerializer();
var jsonObj = serializer.Deserialize<dynamic>(jsonString);
var newData1 = jsonObj["newData"][0];
person Si Phillipson    schedule 12.11.2010
comment
+1 за рабочий ответ. Проблема в том, что, поскольку мой json был в JsonResult, мне нужно было сериализовать его в строку, а затем десериализовать обратно в динамику, что менее идеально. - person Matt Roberts; 12.11.2010