1

I have a method that returns List<IDictionary<string,object>>.

The objects for the dictionary are created using ExpandoObject and then added to the list with foreach loop. Here is the example of such object:

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";

From what the method returns, I need to select distinct values of the "DateTime Property 1", but only for date part of it. So, I'm trying to do the following:

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

But it says that there is no such method as ToShortDateString():

IEnumerable' does not contain a definition for 'ToShortDateString' and no extension method 'ToShortDateString' accepting a first argument of type 'IEnumerable' could be found.

Why is the object in the dictionary not converted to DateTime type automatically when property is assigned a DateTime value? When I use dynamic everywhere instead of object, everything works fine.

How do I make it work when using object?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
YMM
  • 632
  • 1
  • 10
  • 21

1 Answers1

1

Your method returns List<IDictionary<string,object>>, so when you access an item within the Dictionary, the compiler will treat it as an object and so will detect that there is no method ToShortDateString defined on it.

If your method instead returns List<dynamic> and you access an element as a dynamic, the compiler will not check whether or not ToShortDateString exists, and so you will get no errors.

If you know s["DateTime Property 1"] is a DateTime, then you can simply cast it

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

Alternatively, you can call ToString then parse the result

DateTime.Parse(s["DateTime Property 1"].ToString()).ToShortDateString();
KMoussa
  • 1,568
  • 7
  • 11
  • Yes, "DateTime Property 1" is of type `DateTime`. It's calculated by `DateTimeOffset.Parse(JTokenValue.ToString()).DateTime` within a method mentioned above. Trying to cast `DateTime` did not help: the error about missing `ToShortDateString()` method still remains. Calling `ToString()` prior to `ToShortDateString()` does not work as `ToShortDateString()` expects `DateTime` as an argument, not a `string` (the error about that appears). – YMM Nov 25 '16 at 19:07
  • can you include the code you used to cast to `DateTime`? – KMoussa Nov 25 '16 at 19:08
  • `var unique = GetData().Select(s => (DateTime)s["DateTime Property 1"].ToShortDateString()).Distinct();` – YMM Nov 25 '16 at 19:15
  • You're missing brackets, `var unique = GetData().Select(s => ((DateTime)s["DateTime Property 1"]).ToShortDateString()).Distinct();` should work – KMoussa Nov 25 '16 at 19:16