Based on David Culp's answer, I made this extension function:
public static object With(this object obj, object additionalProperties)
{
var type = additionalProperties.GetType();
foreach (var sourceField in type.GetFields())
{
var name = sourceField.Name;
var value = sourceField.GetValue(additionalProperties);
if (type.GetMember(name)[0] is FieldInfo)
type.GetField(name).SetValue(obj, value);
else
type.GetProperty(name).SetValue(obj, value);
}
return obj;
}
and it's used like this:
var myClassInstance = myFactory.CreateMyClass().With(new { MyPropertyA = "blah", MyPropertyB = "bleh"});
It really shines when there's a lot of properties.
// insert a new version
T newVersion = (T)MemberwiseClone();
newVersion.IsSuspended = true;
newVersion.RealEffectiveDate = RealExpirationDate;
newVersion.RealExpirationDate = NullDate;
newVersion.Version++;
newVersion.BusinessEffectiveDate = BusinessExpirationDate;
newVersion.BusinessExpirationDate = NullDate;
becomes:
// insert a new version
T newVersion = (T)MemberwiseClone().With(new
{
IsSuspended = true,
RealEffectiveDate = RealExpirationDate,
RealExpirationDate = NullDate,
Version = Version + 1,
BusinessEffectiveDate = BusinessExpirationDate,
BusinessExpirationDate = NullDate
});