You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断含自定义类属性的两个对象属性值是否匹配?

对象属性匹配方案的问题与解决

问题背景

正在实现一个判断两个对象是否匹配的方案,规则为:若两个对象拥有同名属性,则属性值需匹配。现有Solution(SC)和Device(DI)两个类,Test属性可正确判定为匹配,但Little类属性因SC和DI使用不同实例,尽管属性值一致仍被判定为不匹配。

代码示例

namespace HelloWorld
{
    using System;
    using System.Reflection;

    public class Little
    {
        public string L1 { get; set; }
        public string L2 { get; set; }
    }
    
    public class Solution
    {
        public string Name { get; set; }
        public string Test { get; set; }
        public Little L {get; set; }
    }
    
    public class Device
    {
        public string Name { get; set; }
        public string Test { get; set; }
        public Little L {get; set; }
    }
    
    public class Program
    {
        static void Main(string[] args)
        {
            var Li = new Little {
                L1 = "L1111",
                L2 = "L2222"
            };
            var Li2 = new Little {
                L1 = "L1111",
                L2 = "L2222"
            };
            var SC = new Solution {
                Name = "SC",
                Test = "T1",
                L = Li2
            };
            var DI = new Device {
                Name = "DI",
                Test = "T1",
                L = Li
            };
            
            foreach (var property in SC.GetType().GetProperties())
            {
                var deviceProperty = DI.GetType().GetProperty(property.Name);
                if (deviceProperty != null)
                {
                    if (deviceProperty.GetValue(DI) != property.GetValue(SC))
                    {
                        // 这里会判定不匹配,因为DI和SC的Little是不同实例,但属性值完全一致
                        // 如何判断属性是否为自定义类(避免将string等引用类型误判)?
                        // 若Little类中嵌套其他类,是否需要递归遍历直到属性为值类型?
                    }
                    else
                    {
                        Console.WriteLine("We have a match");
                    }
                }
            }
        }
    }
}

疑问

  1. 如何判断属性是否为自定义类(避免将string等引用类型误判)?
  2. 若Little类中嵌套其他类,是否需要递归遍历直到属性为值类型?

解决思路

1. 区分自定义类与系统引用类型

要避开string这类系统内置的引用类型,核心是过滤系统类型,可以通过以下逻辑实现:

  • 先排除值类型、接口,这些肯定不是自定义类;
  • 单独排除string(它是引用类型但属于系统内置);
  • 最后检查类型的命名空间是否以System.开头,自定义类的命名空间一般是你自己定义的(比如示例中的HelloWorld),不会属于System体系。

工具方法代码:

private static bool IsCustomClass(Type type)
{
    if (type.IsValueType || type.IsInterface)
        return false;
    if (type == typeof(string))
        return false;
    return !type.Namespace?.StartsWith("System.", StringComparison.OrdinalIgnoreCase) ?? false;
}

2. 嵌套类的递归比较

如果自定义类里嵌套了其他自定义类,必须递归遍历比较。只有递归到最底层的值类型、字符串等,才能准确判断属性值是否完全匹配。

可以写一个递归的比较方法,逻辑如下:

  • 先处理null情况:都null则匹配,一个null一个非null则不匹配;
  • 如果是值类型或string,直接用Equals比较;
  • 如果是自定义类,遍历所有属性,递归调用比较方法;
  • 其他系统引用类型(如集合、数组)可根据需求扩展处理逻辑。

完整递归比较方法:

private static bool AreObjectsMatching(object obj1, object obj2)
{
    // 处理null情况
    if (obj1 == null && obj2 == null)
        return true;
    if (obj1 == null || obj2 == null)
        return false;
    
    Type type1 = obj1.GetType();
    Type type2 = obj2.GetType();
    
    // 值类型或字符串直接比较
    if (type1.IsValueType || type1 == typeof(string))
    {
        return obj1.Equals(obj2);
    }
    
    // 自定义类递归比较属性
    if (IsCustomClass(type1))
    {
        foreach (PropertyInfo prop in type1.GetProperties())
        {
            PropertyInfo prop2 = type2.GetProperty(prop.Name);
            if (prop2 == null)
                continue;
            
            object value1 = prop.GetValue(obj1);
            object value2 = prop2.GetValue(obj2);
            
            if (!AreObjectsMatching(value1, value2))
                return false;
        }
        return true;
    }
    
    // 其他系统引用类型,默认用Equals判断(可按需扩展)
    return obj1.Equals(obj2);
}

替换原有逻辑

在Main方法中,把原来的直接引用比较替换为递归比较:

foreach (var property in SC.GetType().GetProperties())
{
    var deviceProperty = DI.GetType().GetProperty(property.Name);
    if (deviceProperty != null)
    {
        object scValue = property.GetValue(SC);
        object diValue = deviceProperty.GetValue(DI);
        
        if (AreObjectsMatching(scValue, diValue))
        {
            Console.WriteLine($"Property {property.Name} matches");
        }
        else
        {
            Console.WriteLine($"Property {property.Name} does NOT match");
        }
    }
}

这样就能正确判断Little这类自定义类的属性值是否匹配,哪怕是不同实例,只要内部属性值一致就会判定为匹配;如果Little里嵌套了其他自定义类,递归逻辑也能逐层比较。


内容的提问来源于stack exchange,提问作者sarah campolt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 04:12:10