Подсчет объектов в динамическом анонимном объекте (C#)

У меня есть динамический объект (на самом деле это json), который я передаю в свой контроллер MVC WebApi.

Объект json содержит несколько списков в анонимном объекте, которые передаются контроллеру из другого приложения через client.PostAsJsonAsync("myapiurl", objectGraph).

Что мне нужно сделать для проверки объекта на стороне MVC, так это получить количество объектов в каждом списке. Я могу получить динамический доступ к спискам через mydynamicobject.mylist и к отдельным элементам через mydynamicobject.mylist[index], но я не могу подсчитать mydynamicobject.mylist.

Что я пробовал до сих пор:

  • Методы расширения LINQ — не работают с динамическими
  • Enumerable.Count(mydynamicobject.mylist) - не может определить тип

Любые другие идеи? Счетчик на самом деле правильно доступен в base динамического объекта, но, очевидно, недоступен как свойство. Помощь!

Это работает сейчас:

// This is a MVC/WebApi method
public dynamic Post(dynamic mydynamicobject)

if (((ICollection)mydynamicobject.mylist).Count == 0)
{
// do something
}

Код, который отправляет динамический объект (другое приложение):

HttpClient client = new HttpClient();  
client.DefaultRequestHeaders.Accept.Add
  (new MediaTypeWithQualityHeaderValue("application/json")); 

var objectGraph = new { mylist = new { Id = 1 }, mylist2 = new { Name = "ABC" } }; 
var r = client.PostAsJsonAsync("api/mycontroller", objectGraph).Result;

person Alex    schedule 29.11.2012    source источник
comment
В какой момент mydynamicobject.mylist терпит неудачу - время компиляции или время выполнения?   -  person Jon Skeet    schedule 30.11.2012
comment
Я только не могу подсчитать список в динамическом объекте. Неудача зависит от того, что я пытаюсь. Enumerable.Count скажет, что не может вывести тип и указать его явно.   -  person Alex    schedule 30.11.2012
comment
Извините, я имел в виду с Enumerable.Count - это ошибка во время выполнения или во время компиляции? Какой является типом времени выполнения mydynamicobject.mylist?   -  person Jon Skeet    schedule 30.11.2012
comment
Это во время выполнения. Не уверен, какой тип будет, учитывая, что объект является динамическим. Во время создания это простой список анонимного типа (например, новый x { новый a { a1 = 1 }, новый b { b1 = 1 } }).   -  person Alex    schedule 30.11.2012
comment
Этот код не будет компилироваться — если бы вы могли создать короткий, но полный пример, было бы намного проще убедиться, что мы дали вам что-то работающее.   -  person Jon Skeet    schedule 30.11.2012
comment
@JonSkeet С нетерпением жду вашего разъяснения, почему это работает именно так, через минуту. (В настоящее время я работаю над проектом Ruby/Javascript, поэтому у меня нет практики C#)   -  person Chris Pfohl    schedule 30.11.2012
comment
@Alex: mylist здесь не список - это просто объект с одним свойством Id. Я удивлен, что это вообще работает, с точки зрения приведения к ICollection...   -  person Jon Skeet    schedule 30.11.2012
comment
Действительно, вы уверены, что публикуете именно этот JSON? Потому что это вообще не должно работать, так как mylist не является списком. Кроме того, вы можете попробовать удалить приведение к ICollection и проверить, работает ли mydynamicobject.mylist.Count == 0 для вас? Актерский состав в данном случае кажется излишним.   -  person Paolo Moretti    schedule 30.11.2012
comment
Да, это должен быть JSON. mydynamicobject.mylist.Count не работает (возвращает ноль). Вы правы в том, что моя тестовая программа на самом деле не была списком; Я изменил это и сделал настоящий список. Код ICollection работает как прежде.   -  person Alex    schedule 30.11.2012
comment
Сейчас выглядит так: var objectGraph = new { mylist = new { mylistobject1= new { Id = 1 }, mylistobject2 = new { Id = 2 } }, (...)   -  person Alex    schedule 30.11.2012


Ответы (1)


Если это массивы, я полагаю, вы ищете их свойство Length.

mydynamicobject.mylist.Length

В качестве альтернативы, я думаю, вы могли бы уйти от приведения mydynamicobject.mylist к IEnumerable, а затем передать его IEnueramble.Count следующим образом:

IEnumerable.Count((IEnumerable)mydynamicobject.mylist);

вы могли бы также сделать, как упомянул Паоло:

((ICollection)mydynamicobject.mylist).Count

Хотя я не могу взять на себя ответственность за это.

person Chris Pfohl    schedule 29.11.2012
comment
Вы имеете в виду ICollection.Count - person Paolo Moretti; 30.11.2012
comment
@PaoloMoretti Спасибо. Исправление. - person Chris Pfohl; 30.11.2012
comment
Извините, я был недостаточно ясен. Вы можете попытаться преобразовать его в ICollection, а затем проверить ICollection.Count или преобразовать его в IEnumerable и использовать метод расширения LINQ Enumerable.Count - person Paolo Moretti; 30.11.2012
comment
Я смог передать его в ICollection. Код кажется немного уродливым, но, по крайней мере, он работает. Спасибо! - person Alex; 30.11.2012
comment
@JonSkeet гораздо лучше объяснил бы, почему компилятор и динамика ведут себя таким образом. Мне пришлось бы откопать мою копию C# in Depth... и это было бы почти как украсть ответ Джона. - person Chris Pfohl; 30.11.2012