One way to do this is with Expressions, allthough I believe that's complete overkill for something like this. Your method signature would look like the following:
Party CloneParty(int id, Expression<Func<Party>> valueMergeSelector);
The invocation would look as follows:
var clonedParty = CloneParty(5, () => new Party { Role = PartyRole.Whatever });
The implementation of this method would be unnecessarily complicated and involve compiling and executing the expression, storing the new Party's values, using a custom subclass of ExpressionVisitor
designed to figure out which of that Party's
properties were assigned, create a bag to store those properties, clone the original object, and then loop over the bag to assign the new Party's applicable values (as indicated by the bag's index) to the clone's properties, and return the clone with the newly assigned values.
This would ensure that any value on Party could be set without having to worry about optional parameters, or wrapping each of the properties values in some sort of "IsARealValue
" class, such as with Nullable
.
The only real use case for something like this is a public-facing API which would require you (the api-developer) to know what values are being assigned at run time, for the purpose of query construction, etc.
Edit
After talking with @River, it sounds like trying to make a clone method with the ability to assign new values is, in most cases, just over-engineering a very simple existing pattern:
var clone = GetClone(5);
clone.Role = PartyRole.Whatever;
Unless there's a reason this wouldn't work, it's probably the most elegant solution, seeing as how no-body has to figure out how to use it.