如何优雅地编写以下方法?

时间:2017-09-06 14:11:46

标签: c# methods overloading optional-parameters

我有以下方法签名:

Party cloneParty(bool useGivenParams, int i_PartyId, PartyRole i_PartyRole, DeletedState i_Deleted)

以及名为m_PartiesById的现有政党的成员集合。

是否有一种优雅的方法来编写方法来实现以下行为:

  1. 我希望能够仅使用ID调用该方法,在这种情况下,我想要恢复该方的副本(如果该ID存在于集合中)不变。例如:

    Party identicalClone = cloneParty(123);
    
  2. 我希望只能使用ID 调用该方法,我想在克隆中创建的参数更改 。例如:

    Party slightlyChangedClone = cloneParty(123, PartyRole.To);
    

2 个答案:

答案 0 :(得分:1)

为什么不将可选参数默认为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并根据需要设置任何属性来手动执行此操作。

答案 1 :(得分:1)

这样做的一种方法是使用表达式,尽管我认为这样的事情完全矫枉过正。您的方法签名如下所示:

Party CloneParty(int id, Expression<Func<Party>> valueMergeSelector);

调用如下:

var clonedParty = CloneParty(5, () => new Party { Role = PartyRole.Whatever });

此方法的实现将不必要地复杂化,并且涉及编译和执行表达式,存储新的Party的值,使用ExpressionVisitor的自定义子类来设计哪个{{1}已分配属性,创建一个用于存储这些属性的包,克隆原始对象,然后在包上循环以将新的Party的适用值(由包的索引指示)分配给克隆的属性,并使用新分配的值返回克隆。

这将确保可以设置Party上的任何值,而无需担心可选参数,或将某些属性值包装在某种类型的&#34; Party's&#34;类,例如IsARealValue

这样的唯一真实用例是面向公众的API,它需要您(api-developer)知道在运行时分配的值,目的是查询构造等

<强> 修改

在与@River交谈后,听起来像尝试制作一个能够分配新值的克隆方法,在大多数情况下,只是过度设计一个非常简单的现有模式:

Nullable

除非这是一个不起作用的原因,否则它可能是最优雅的解决方案,看看无人体必须弄清楚如何使用它。