如何优雅地编写以下方法? [关闭]

问题描述 投票:-2回答:2

我有以下方法签名:

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);
c# methods overloading optional-parameters
2个回答
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而不是??语句。

Do you really need the method?

作为I discussed with Christopher,通过克隆Party并根据需要设置任何属性,您可能手动更好。


1
投票

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

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;

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

© www.soinside.com 2019 - 2024. All rights reserved.