使用 C# 比较嵌套对象属性

2024-03-27

我有一个方法可以比较两个对象并返回所有不同属性名称的列表。

public static IList<string> GetDifferingProperties(object source, object target)
{
    var sourceType = source.GetType();
    var sourceProperties = sourceType.GetProperties();
    var targetType = target.GetType();
    var targetProperties = targetType.GetProperties();

    var properties = (from s in sourceProperties
                      from t in targetProperties
                      where s.Name == t.Name &&
                            s.PropertyType == t.PropertyType &&
                            s.GetValue(source,null) != t.GetValue(target,null)
                      select s.Name).ToList();
    return properties;
}

例如,如果我有两个类,如下所示:

public class Address
    {
        public string AddressLine1 { get; set; }
        public string AddressLine2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Zip { get; set; }
    }

       public class Employee
        {
            public string FirstName { get; set; }
            public string MiddleName { get; set; }
            public string LastName { get; set; }
            public Address EmployeeAddress { get; set; }
        }

我试图比较以下两个员工实例:

var emp1Address = new Address();
        emp1Address.AddressLine1 = "Microsoft Corporation";
        emp1Address.AddressLine2 = "One Microsoft Way";
        emp1Address.City = "Redmond";
        emp1Address.State = "WA";
        emp1Address.Zip = "98052-6399";

        var emp1 = new Employee();
        emp1.FirstName = "Bill";
        emp1.LastName = "Gates";
        emp1.EmployeeAddress = emp1Address;


        var emp2Address = new Address();
        emp2Address.AddressLine1 = "Gates Foundation";
        emp2Address.AddressLine2 = "One Microsoft Way";
        emp2Address.City = "Redmond";
        emp2Address.State = "WA";
        emp2Address.Zip = "98052-6399";

        var emp2 = new Employee();
        emp2.FirstName = "Melinda";
        emp2.LastName = "Gates";
        emp2.EmployeeAddress = emp2Address;

因此,当我将这两个员工对象传递给 GetDifferingProperties 方法时,当前它会返回 FirstName 和 EmployeeAddress,但它不会告诉我 EmployeeAddress 中的哪个确切属性(在本例中为 Address1)已更改。我如何调整此方法以获得类似 EmployeeAddress.Address1 的内容?


这是因为你正在使用!=对于对象,它测试对象的身份而不是其值。关键是使用递归来生成属性的属性列表。这将按照你想要的深度进行...

public static IList<string> GetDifferingProperties(object source, object target)
{
  var sourceType = source.GetType();
  var sourceProperties = sourceType.GetProperties();
  var targetType = target.GetType();
  var targetProperties = targetType.GetProperties();

  var result = new List<string>();

  foreach (var property in
      (from s in sourceProperties
       from t in targetProperties
       where s.Name == t.Name &&
       s.PropertyType == t.PropertyType &&
       !Equals(s.GetValue(source, null), t.GetValue(target, null))
       select new { Source = s, Target = t }))
  {
    // it's up to you to decide how primitive is primitive enough
    if (IsPrimitive(property.Source.PropertyType))
    {
      result.Add(property.Source.Name);
    }
    else
    {
      foreach (var subProperty in GetDifferingProperties(
          property.Source.GetValue(source, null),
          property.Target.GetValue(target, null)))
      {
        result.Add(property.Source.Name + "." + subProperty);
      }
    }
  }

  return result;
}

private static bool IsPrimitive(Type type)
{
  return type == typeof(string) || type == typeof(int);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 C# 比较嵌套对象属性 的相关文章

随机推荐

  • 启动失败。未找到二进制文件。 Eclipse Helios 上的 CDT

    我在 Ubuntu 10 04 上使用 Eclipse Helios 并尝试在其上安装 CDT 插件 我从这里下载here http www eclipse org downloads download php file tools cdt
  • 换行 NSButton 标题

    有什么方法可以让 NSButton 标题在宽度比按钮宽度长时换行 而不是被剪裁 我正在尝试创建一个单选按钮 其中的文本可能很长并且有多行 我考虑让它工作的一种方法是使用 NSRadioButton 类型的 NSButton 但无法让多行文本
  • 合并 2 个视频文件时出现问题 [匹配规格后]

    基本上我得到了一个 mp4 和一个 flv 文件 我想连接它们 mp4 应该是简介 所以在问了一个之前关于此的问题 https stackoverflow com questions 34029123 combine 2 flv video
  • 捆绑包标识符与保留捆绑包标识符不同

    我正在尝试在 iTunes 上上传我的应用程序 为此 我创建了一个应用程序 ID 并保留了一个包标识符 在我的项目中 我更改了 info plist 文件中的包标识符 但是 当我尝试在 itunes 上上传我的应用程序时 它显示错误 捆绑包
  • 如何使模式弹出窗口随页面滚动其内容?

    我有一个模式弹出窗口 当它加载高于浏览器高度的内容时 我无法向下滚动以查看其余信息 相反 背景可以滚动 但弹出窗口不会 相反 我想让弹出窗口保持不变 当用户向上或向下滚动时 它会将弹出窗口保留在适当的位置 并让他们滚动到内容的底部 如果您在
  • 为 libcurl 添加自签名 SSL 证书

    我在我的 C 应用程序中使用 libcurl 与我设置的 HTTPS 服务器进行通信 我在该服务器上生成了一个自签名证书 我希望将其与curl 一起使用 我知道将 CURLOPT SSL VERIFYPEER 设置为 0 可以绕过 SSL
  • SQL Server 2014 中具有多个条件的情况

    我有一个表 FinancialTrans 其中有很多字段 但其中只有 3 个字段与我有关 AcctID TransTypeCode DateOfTrans Field 4 Field 5 Field 6 123 TOLL 2016 06 0
  • 如何在 yii 的更新视图中加载多选列表框中选定的列表项?

    我有一个multiple select list box for Staff in Create Service Form 用于在创建新服务时选择多名员工 为此 我可以在一项服务上分配多名员工 I saved staff id字段为 mod
  • 如何对特定文件夹设置777权限? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何对文件夹设置777权限 我需要将以下文件夹的权限设置为777 管理 包含 模块 安装 我不知道如何在 Windows 7 中的特定文件
  • System.Runtime,Version=4.2.1.0,PublicKeyToken=b03f5f7f11d50a3a 的版本高于引用的程序集

    我将 ASP NET CORE 应用程序从 sdk NET Core 2 0 升级到 NET Core 2 1 我可以在本地主机中运行该解决方案 但是当我将其部署到另一台服务器时出现异常 例外情况如下 到目前为止 我为解决该问题所做的步骤如
  • 单击按钮后 React hooks useInterval 重置

    我有钩子 useInterval 它每 10 秒自动下载一次数据 但是我也有按钮 可以在每时每刻手动下载数据 当我单击按钮时 我很难重新启动间隔计时器 所以基本上 如果间隔计数到 5 但我同时单击按钮 间隔应该重新启动 并在下载数据之前再次
  • link_to image_tag 与 Rails 中的内部文本或 html

    我想用 Ruby on Rails 输出以下内容link to and image tag方法 a href Lorem Ipsum img src images menu arrow down gif a Rails 中什么是好方法 您可
  • 为什么在 window 对象中定义 body [重复]

    这个问题在这里已经有答案了 我只是在控制台上玩 注意到如果我输入 body它返回 这显然与window body 因此也返回了 Then document body也返回 正如预期的那样 因为身体是身体的一部分document对象 据我所知
  • CakePhp - 关联数据未保存(但主模型数据确实保存)

    所以 我在 CakePhp 中有一个使用 Formhelper 的表单 此表单中有两个关联模型 Booking 和 Guest 数据库表似乎设置正确 因为页面通过模型中的关联足够准确地填充了值 保存表单数据时 会保存预订信息 但不会保存宾客
  • 如何找出Oracle死锁的原因

    当使用多个用户测试我的应用程序时 我遇到了 ORA 00060 死锁错误 我不确定如何确定此错误的原因 因此如果有人可以帮助我 我将不胜感激 我查看了为此事件生成的跟踪文件 它显示了哪个查询导致了此事件 UPDATE TABLE A SET
  • Google Ads API - “失败,状态为“PERMISSION_DENIED” - “用户无权访问客户。”

    我正在尝试使用 Google ads API 运行 Ubuntu 20 04 Python 3 9 客户端库工作的最低要求是 3 6 使用 google ads api V6 这是我的痛苦故事 我创建了一个测试管理员帐户 A 生成了开发人员
  • 如何使用 grunt-sass 编译多个 scss 文件

    我正在尝试将多个 scss 文件编译为单个 CSS 文件 这实际上有效 但只获取第一个文件 sass Task dist files css test css sass scss 我们没有安装 ruby 所以 grunt contrib s
  • React Hooks:如何在 useEffect 中设置 State?

    我正在尝试从 firebase 获取数据并使用 useState 挂钩将检索到的数据设置为我的状态 我知道我的 API 调用正在工作 因为我可以从 firebase 记录数据 但当我使用 setState 时 它并没有达到我的状态 由于某种
  • 为什么 R 有时会停止显示输出?

    有时 R 会停止显示输出 我输入数字 1 然后按回车键 但什么也没有出现 这种情况是在我按下窗口中的 停止 图标后发生的 该图标用于停止长时间的计算 我在 Mac 上使用 R 2 11 0 按 STOP 是否会导致 R 停止显示输出 如何让
  • 使用 C# 比较嵌套对象属性

    我有一个方法可以比较两个对象并返回所有不同属性名称的列表 public static IList