【问题标题】:Is there a way to make this C# comparison code more generic?有没有办法让这个 C# 比较代码更通用?
【发布时间】:2012-07-09 02:26:16
【问题描述】:

我正在比较两个相同类型的对象并将差异返回到FieldChange 对象列表中。现在我列出了这样的每个字段比较,这似乎有点不理想。

有没有更简洁的方法来重构下面的代码以避免重复?下面有两组代码,但实际上我有大约 20 个比较。

var changes = new List<FieldChange>();
if (proposedUpdatedProject.StatusId != existingProject.StatusId)
{
    var previousStatusName = existingProject.StatusShortName;
    existingProject.Status = ProjectModel.Repository.Fetch<ProjectStatus>(proposedUpdatedProject.StatusId);
    changes.Add(new FieldChange { FieldName = "Status", PreviousValue = previousStatusName, NewValue = existingProject.StatusShortName });
}

if (proposedUpdatedProject.TechOwnerId != existingProject.TechOwnerId)
{
    var previousTechOwnerName = existingProject.TechOwnerName;
    existingProject.TechOwner = ProjectModel.Repository.Fetch<Person>(proposedUpdatedProject.TechOwnerId);
    changes.Add(new FieldChange { FieldName = "Tech Owner", PreviousValue = previousTechOwnerName, NewValue = existingProject.TechOwnerName });
}   

注意:所有对象都派生自同一个名为 BaseObj 的对象。另请注意,我不只是将可比较字段的值放入 FieldChange 对象(id 与 Name 属性)

【问题讨论】:

标签: c# refactoring


【解决方案1】:

您可以创建一个方法attribute,例如称为ComparableAttribute。 然后你可以用这个属性来装饰这些对象中的所有方法。

您可以在进行比较的方法中使用反射并遍历所有Comparable 属性。代码会更短(一次迭代,而不是 20 个if 语句)。

如果您需要某些属性的自定义信息,您可以通过ComparableAttribute 属性将其指定为参数。

compare 方法仍将两个实例作为参数,但您最终会得到一个更小的实现。您甚至可以为您的类型缓存PropertyInfos,这样您就不会在每次比较时进行反映。

【讨论】:

  • 您能否阐明如何使用这种方法指示 StatusId 和 StatusShortName 之间的关系?
  • @leora:我会在ComparableAttribute 中使用参数。例如:Comparable(Name="Status", ValueProperty="StatusShortName", LookupPropertyType=typeof(ProjectStatus))。在比较函数中,您可以使用它来概括您现在在 if 语句中拥有的代码。
  • @leora: 错过了身份证。应该是Comparable(Name="Status", IdProperty="StatusId", ValueProperty="StatusShortName", LookupPropertyType=typeof(ProjectStatus))。如果我仔细想想,这应该是类属性,而不是方法属性,因为您只需要对象属性的子集。
  • 这应该是一个类属性是什么意思?你会在类的顶部列出每个可比较的字段(你列出的属性)吗?
【解决方案2】:

为什么不反映到结构中:

existingProject

并比较所有字段。通过以这种方式长期编写代码,您正在为问题添加大量信息,例如 StatusID 和 StatusName 之间的关联,但是如果您选择一些适当的命名约定,您可能会自动完成整个事情。

【讨论】:

    【解决方案3】:

    为什么不使用INotifyPropertyChanged 接口?查看here 了解相关信息。您只需实现它并订阅该事件。再来一个link

    【讨论】:

      猜你喜欢
      • 2020-06-25
      • 1970-01-01
      • 1970-01-01
      • 2019-12-11
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      • 1970-01-01
      • 2020-07-29
      相关资源
      最近更新 更多