我有以下方法签名:
Party cloneParty(bool useGivenParams, int i_PartyId, PartyRole i_PartyRole, DeletedState i_Deleted)
还有一个名为m_PartiesById
的现有政党成员集合。
是否有一种优雅的方法来编写方法来实现以下行为:
Party identicalClone = cloneParty(123);
Party slightlyChangedClone = cloneParty(123, PartyRole.To);
为什么不将可选参数默认为null
,并且只更改不是null
的值:
Party cloneParty(int i_Id, PartyRole i_PartyRole = null, DeletedState i_Deleted = null){
Party clone = #clone party from i_Id here
clone.PartyRole = i_PartyRole ?? clone.PartyRole;
clone.DeletedState = i_Deleted ?? clone.DeletedState;
return clone;
}
看起来PartyRole
可能是enum
,在这种情况下你需要PartyRole? i_PartyRole = null
(注意添加的问号)。
如果您愿意,也可以使用if(i_PartyRole != null) clone.PartyRole = i_PartyRole
而不是??
语句。
作为I discussed with Christopher,通过克隆Party
并根据需要设置任何属性,您可能手动更好。
一种方法是使用表达式,尽管我认为这样的事情完全有点过头了。您的方法签名如下所示:
Party CloneParty(int id, Expression<Func<Party>> valueMergeSelector);
调用如下:
var clonedParty = CloneParty(5, () => new Party { Role = PartyRole.Whatever });
这种方法的实现将不必要地复杂化,并且涉及编译和执行表达式,存储新的Party的值,使用ExpressionVisitor
的自定义子类来设计哪个Party's
属性被分配,创建一个包来存储这些属性,克隆原始对象,然后在包上循环以将新的Party的适用值(由包的索引指示)分配给克隆的属性,并使用新分配的值返回克隆。
这将确保可以设置Party上的任何值,而无需担心可选参数,或将某些属性值包装在某种“IsARealValue
”类中,例如使用Nullable
。
对于这样的事情,唯一真实的用例是面向公众的API,它需要您(api-developer)知道在运行时分配的值,用于查询构造等。
编辑
在与@River交谈后,听起来像尝试制作一个能够分配新值的克隆方法,在大多数情况下,只是过度设计一个非常简单的现有模式:
var clone = GetClone(5);
clone.Role = PartyRole.Whatever;
除非有这样的理由不起作用,否则它可能是最优雅的解决方案,看看无人体必须弄清楚如何使用它。