Adding extra properties to an anonymous class

asp.net-mvc, c#

Solution

Thanks to a comment from Patryk I gave it a go using an ExpandoObject and got it working like this:

dynamic viewData = new ExpandoObject();
viewData.@class = cssClasses;
if (controlId != null)
  viewData.id = controlId;
if (title != null)
  viewData.title = title;
// put the result into a route value dictionary so that MVC's EditorFor (etc) can interpret it
var additionalViewData = new RouteValueDictionary(viewData);

That last line was the key to getting it working in MVC so that it could be passed as the additionalViewData parameter in EditorFor etc.

In the situations where I'm being passed an anonymous class and need to add to it myself, I'm using reflection (and taking advantage of ExpandoObject implementing IDictionary). Here's the unit test I wrote to check that it works:

[TestMethod]
public void ShouldBeAbleToConvertAnAnonymousObjectToAnExpandoObject()
{
  var additionalViewData = new {id = "myControlId", css = "hide well"};
  dynamic result = new ExpandoObject();
  var dict = (IDictionary<string, object>)result;
  foreach (PropertyInfo propertyInfo in additionalViewData.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
  {
    dict[propertyInfo.Name] = propertyInfo.GetValue(additionalViewData, null);
  }
  Assert.AreEqual(result.id, "myControlId");
  Assert.AreEqual(result.css, "hide well");
}

Problem

Is there a way to add extra properties to an anonymous class (or create a new instance with the extra properties)? ``` string cssClasses = "hide"; object viewData = new { @class = cssClasses }; if (suppliedId != null) { // add an extra id property to the viewData somehow... // desired end result is { @id = suppliedId, @class = cssClasses } } // ... code will be passing the viewData as the additionalViewData parameter in asp.mvc's .EditorFor method ```

Original source