Question

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 isdynamic {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.

Was it helpful?

Solution 2

I figured out my issue. Where I was creating the IEnumerable of dynamics, I just needed to convert it to an array, like so:

expandoDic.Add(new KeyValuePair<string, dynamic>(f.Code, f.Values.Select(v => GetTypedValue(f.GetValueType(), v)).ToArray()));

This proves yet again that having to explain the problem thoroughly can often reveal the answer.

OTHER TIPS

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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top