Выберите отдельные свойства DateTime из List‹IDictionary‹string,object›› с помощью LINQ

У меня есть метод, который возвращает List<IDictionary<string,object>>.

Объекты для словаря создаются с помощью ExpandoObject, а затем добавляются в список с помощью цикла foreach. Вот пример такого объекта:

var dataItem = new ExpandoObject() as IDictionary<string, object>;
dataItem["String Property 1"] = "String Value 1";
dataItem["String Property 2"] = "String Value 2";
dataItem["DateTime Property 1"] = "DateTime Value 1";
dataItem["DateTime Property 2"] = "DateTime Value 2";

Из того, что возвращает метод, мне нужно выбрать разные значения «свойства DateTime 1», но только для его части даты. Итак, я пытаюсь сделать следующее:

var unique = GetData().Select(s => s["DateTime Property 1"].ToShortDateString()).Distinct();

Но там написано, что такого метода как ToShortDateString() нет:

IEnumerable» не содержит определения для «ToShortDateString», и не удалось найти метод расширения «ToShortDateString», принимающий первый аргумент типа «IEnumerable».

Почему object в словаре не преобразуется автоматически в тип DateTime, когда свойству присваивается значение DateTime? Когда везде использую dynamic вместо object все работает нормально.

Как заставить его работать при использовании object?


person YMM    schedule 25.11.2016    source источник


Ответы (1)


Ваш метод возвращает List<IDictionary<string,object>>, поэтому, когда вы обращаетесь к элементу в Dictionary, компилятор будет рассматривать его как object и, таким образом, обнаружит, что для него не определен метод ToShortDateString.

Если вместо этого ваш метод возвращает List<dynamic> и вы обращаетесь к элементу как dynamic, компилятор не будет проверять, существует ли ToShortDateString, и поэтому вы не получите ошибок.

Если вы знаете, что s["DateTime Property 1"] — это DateTime, вы можете просто разыграть его.

((DateTime)s["DateTime Property 1"]).ToShortDateString();

В качестве альтернативы вы можете вызвать ToString, а затем проанализировать результат.

DateTime.Parse(s["DateTime Property 1"].ToString()).ToShortDateString();
person KMoussa    schedule 25.11.2016
comment
Да, свойство DateTime 1 имеет тип DateTime. Он рассчитывается DateTimeOffset.Parse(JTokenValue.ToString()).DateTime методом, упомянутым выше. Попытка кастовать DateTime не помогла: ошибка об отсутствующем методе ToShortDateString() осталась. Вызов ToString() перед ToShortDateString() не работает, так как ToShortDateString() ожидает DateTime в качестве аргумента, а не string (появляется ошибка об этом). - person YMM; 25.11.2016
comment
можете ли вы включить код, который вы использовали для приведения к DateTime? - person KMoussa; 25.11.2016
comment
Вы пропустили скобки, var unique = GetData().Select(s => ((DateTime)s["DateTime Property 1"]).ToShortDateString()).Distinct(); должно работать - person KMoussa; 25.11.2016