I'd like to manipulate some anonymous types, by inspecting property values, and replacing specific values with a new value in certain circumstances. The problem is, anonymous type properties are read only, i.e. they don't have a setter.
My plan is to treat the anonymous types like any other immutable object, and implement a visitor pattern to return a new instance where necessary, with new property values where required.
What I need to make this work, is a way to initialise a new instance of an anonymous type, dynamically, and set the property values.
Is there a way to dynamically call the initializer for a specific object type, via reflection?
Here's some code to give you an idea of what I'm doing...
var newResults = results.Select(r => VisitResult(r));
// recursive function that visits each property of our results, and manipulates the data
// as required
object VisitResult(object result)
{
// if the object is of our specific data type, we need to check if we need to replace it
if (result is IDataRow row)
{
// check if we should replace the value, and return the new value if we have one
return updatedValues.Lookup(row) ?? row;
}
else
{
// this doesn't work for anonymous types, as the properties are read only
// I'd like to declare a new instance of the same anonymous type, and use
// the initialiser, so I can assign new values to the anonymous type properties
foreach (var propertyInfo in result.GetType().GetProperties())
{
// visit the value of each property
propertyInfo.SetValue(row, VisitResult(propertyInfo.GetValue(row)));
}
}
}
If I cannot achieve this via reflection, I will use Expression trees instead, I was just curious if there was a way of using initialisers via reflection, as my Google-fu hasn't managed to turn up anything relevant.
Aucun commentaire:
Enregistrer un commentaire