1

I have an expando, like

dynamic x = new ExpandoObject ();

AddProperty (x, "Name", "Nick");
AddProperty (x, "Seat", "8H");
AddProperty (x, "Code", "11");

Console.WriteLine(x.Name);
Console.WriteLine (x.Seat);
Console.WriteLine (x.Code);

and I use an AddProperty method for the above, as per source found, i.e.

public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
{
     // ExpandoObject supports IDictionary so we can extend it like this
     var expandoDict = expando as IDictionary<string, object>;

     if ( expandoDict.ContainsKey (propertyName) )
         expandoDict[propertyName] = propertyValue;
     else
         expandoDict.Add (propertyName, propertyValue);
}

Now, I use this method to iterate through my Classes (and it works, even for linked classes, i.e. for properties that are defined using other classes, i.e. public anotherClass address { get; set; } etc..) and it works fine so far:

private static void IterateThrough(object source)
{
    Type sourceType = source.GetType(); //Get current object type of source

    //Iterate through all properties of the source object
    foreach (PropertyInfo prop in sourceType.GetProperties
    (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
    {
        var Type = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;

        if (prop.PropertyType.IsClass && prop.PropertyType != typeof(string)) {
            object o = prop.GetValue(source, null);
            IterateThrough(o);
        }

        Console.WriteLine(prop.DeclaringType.Name + "." + prop.Name);
    }
}

However, when I try with the expando, I get an array length error and a stack overflow eventually.

What's the error and ho do I correctly iterate through my objects, so that it can run for both 'normal' case classes as well as my expando?

dbc
  • 104,963
  • 20
  • 228
  • 340
Nick
  • 483
  • 1
  • 6
  • 15
  • I would only use the Expando Object as a staging ground for data. Something you squeeze in the response from a langauge without (strong) typing (JavaScript, PHP, etc) while you figure out the *real* .NET type to use. But basically it is a `Dictionary` with some Syntax sugar, nothing more. – Christopher Feb 02 '20 at 22:53

1 Answers1

1

From a general point of view, the StackOverflowException is caused by the recursion within IterateThrough.

More relevant to your context though is that the ExpandoObject class implements IDictionary<string, object> for its properties, so the solution is to use casting instead of reflection:

IDictionary<string, object> propertyValues = (IDictionary<string, object>) source;

Your IterateThrough method could have a check like this:

if (source is IDictionary<string, object>){
    IDictionary<string, object> propertyValues = (IDictionary<string, object>) source;

    //iterate through your values
}
else{
    //your existing code
}

However, you may find that your existing code will break with other types of objects too.

Leo
  • 5,013
  • 1
  • 28
  • 65