I have an ExpandoObject
which is created like so:
public ExpandoObject Get()
{
var expando = new ExpandoObject();
var expandoDic = (IDictionary<string, dynamic>)expando;
// go through the items in the dictionary and copy over the key value pairs)
foreach (var f in GetFieldList())
{
if (f.MaxValues == 1)
{
var val = f.Values.Count > 0 ? f.Values[0] : null;
if (f.displayType == DisplayType.Entity && f.AttachedEntities != null && f.AttachedEntities.Any())
{
if (f.AttachedEntities.Count == 1)
{
expandoDic.Add(new KeyValuePair<string, dynamic>(f.Code, f.AttachedEntities[0].Get()));
}
else
{
expandoDic.Add(new KeyValuePair<string, dynamic>(f.Code, f.AttachedEntities.Select(e => e.Get())));
}
}
else
{
expandoDic.Add(new KeyValuePair<string, dynamic>(f.Code, GetTypedValue(f.GetValueType(), val)));
}
}
else
{
expandoDic.Add(new KeyValuePair<string, dynamic>(f.Code, (dynamic)f.Values.Select(v => GetTypedValue(f.GetValueType(), v))));
}
}
return expando;
}
The GetTypedValue
simply converts the string value into the appropriate type and returns dynamic
.
The problem I'm getting is that if I add a collection to expandoDic
then I can't access the members without casting it to an ICollection
type. Consider the following code, where myPage is an ExpandoObject created by the above method.
Response.Write(myPage.menu.items[0]);
The menu property is a dynamic object, as is items
. The latter is a collection of strings, though the type is actually IEnumerable<dynamic>'. If I inspect myPage.menu.items, it tells me the type is
dynamic {System.Linq.Enumerable.WhereSelectListIterator}`. The above code produces the following error:
Cannot apply indexing with [] to an expression of type 'object'
If I use First()
instead of an index, I instead get this error:
'object' does not contain a definition for 'First'
I understand that I could cast items
to IEnumerable
and fix the problem right away, but I am writing a development framework and want to remove any barriers to developers using it.
For dynamic types you cannot use the extension method without conversion, but you can use static call of the method so instead of:
var a = yourDynamic.First();
you should write
var a = Enumerable.First(yourDynamic);