C# 如何有效地比较两个对象并计算相等属性的数量?

C# 如何有效地比较两个对象并计算相等属性的数量?,c#,list,C#,List,我正在处理两个包含许多属性的列表。我试图循环遍历列表,并以计数(int)的形式返回两个对象的比较。计数定义为相等的属性数 下面是一个例子: class Object{ public string prop1 {get;set;} //x5 Avg Length (20-30 Char) public double prop2 {get;set;} //x3 } private int CompareProps(Object a, Object b)

我正在处理两个包含许多属性的列表。我试图循环遍历列表,并以计数(int)的形式返回两个对象的比较。计数定义为相等的属性数

下面是一个例子:

    class Object{
     public string prop1 {get;set;} //x5  Avg Length (20-30 Char)
     public double prop2 {get;set;} //x3

    }
    private int CompareProps(Object a, Object b)
    {
        int matchedElements = 0;
        if (a.Prop1 == b.Pro1)
            matchedElements++; ;
        if (a.Prop2 == b.Prop2)
            matchedElements++;

        // More Property Comparisons...

        return matchedElements;
    }
    ///Loops in another method with two Lists of Object, where each list.count = 300
        List1 = getList1Objects();//300 Objects
        List2 = getList2Objects();//300 Objects
        int l1 = List1.Count;
        int l2 = List2.Count;

        Parallel.For(0, l1, i =>
        {
            for (int j = 0; j < l2; j++)
            {
                int k =  CompareProps(List1[i], List2[j]);
            }
        });
类对象{
公共字符串prop1{get;set;}//x5平均长度(20-30个字符)
公共双属性2{get;set;}//x3
}
私有int比较操作(对象a、对象b)
{
int matchedeelements=0;
如果(a.Prop1==b.Pro1)
匹配元素++;
如果(a.Prop2==b.Prop2)
匹配元素++;
//更多财产比较。。。
返回匹配元素;
}
///使用两个对象列表在另一个方法中循环,其中每个list.count=300
List1=getList1Objects()//300件物品
List2=getList2Objects()//300件物品
int l1=List1.Count;
int l2=List2.Count;
对于(0,l1,i=>
{
对于(int j=0;j
但这是非常低效的。在C#中有更好的方法吗?属性可以是字符串、双精度等


谢谢

您可以这样比较它们:

private int CompareProps(Object a, Object b)
{
    int matchedElements = 0;
    var props = a.GetType().GetProperties();
    foreach(var prop in props)
    {
        var vala = prop.GetValue(a);
        var valb = prop.GetValue(b);
        if(vala == valb)
            matchedElements++;

    // More Property Comparisons...
    return matchedElements;
}

它更易于编写和维护,以便将来更改类属性。但要注意,这肯定需要更多的时间。因此,如果您打算比较数百个对象的实例,则不建议使用此方法。

如果两个列表中可能出现相同的对象,您可以通过引用或哈希将
a
b
进行比较,以便快速短路

如果内部列表创建速度较慢(例如,来自DB的查询),如果大小/内存允许,您可以在循环外部拍摄快照
.ToList()


不过就是这样。有时候,工作就是工作。

如果性能真的很重要,我认为您需要,因为它使用哈希集

private static int CompareProps(MyObject a, MyObject b)
{
     var aValues = a.GetType().GetProperties().Select(x => x.GetValue(a, null));
     var bValues = b.GetType().GetProperties().Select(x => x.GetValue(b, null));

     return aValues.Intersect(bValues).Count();
}
下面是示例用法

var a = new MyObject
{
   prop1 = "abc", // same value
   prop2 = "def",
   prop3 = 123,
   prop4 = 456 // same value
};

var b = new MyObject
{
   prop1 = "abc", // same value
   prop2 = "jkl",
   prop3 = 789,
   prop4 = 456 // same value
};

Console.WriteLine(CompareProps(a, b)); // output 2
编辑:

通过运行300X300列表循环测试了我的解决方案

private static void Run()
{
  var alist = new List<MyObject>();
  for (var i = 0; i < 300; i++)
  {
    alist.Add(new MyObject
    {
        prop1 = "abc",
        prop2 = RandomString(),
        prop3 = random.Next(),
        prop4 = 123
    });
  }

  var blist = new List<MyObject>();
  for (var i = 0; i < 300; i++)
  {
     blist.Add(new MyObject
     {
        prop1 = "abc",
        prop2 = RandomString(),
        prop3 = random.Next(),
        prop4 = 123
     });
  }

  var watch = new Stopwatch();
  watch.Start();

  Parallel.For(0, alist.Count, i =>
  {
     for (var j = 0; j < blist.Count; j++)
     {
        Console.WriteLine("Result: " + CompareProps(alist[i], blist[j]));
     }
  });

  Console.WriteLine(watch.Elapsed.TotalSeconds + "  seconds..");
}
private static void Run()
{
var alist=新列表();
对于(变量i=0;i<300;i++)
{
列表添加(新的MyObject)
{
prop1=“abc”,
prop2=RandomString(),
prop3=random.Next(),
prop4=123
});
}
var blist=新列表();
对于(变量i=0;i<300;i++)
{
blist.Add(新的MyObject
{
prop1=“abc”,
prop2=RandomString(),
prop3=random.Next(),
prop4=123
});
}
var watch=新秒表();
watch.Start();
Parallel.For(0,alist.Count,i=>
{
对于(var j=0;j
结果:9.1703053秒


它是O(1),所以一点效率都没有。不过写下来很麻烦;)您是否比较了属性类型或属性值?要比较多少属性?是否可以编辑帖子并显示对象的示例?你应该发布你的循环。OP已经指出他的设计效率低下,并且正在寻找比他2分钟解决方案更好的方法。他的意思是写得更快而不是更少的代码。2分钟的解决方案不一定是坏的。他在哪里提到更快?就像7分钟的腹肌,人们指的是6分钟的VHS版本。这是暗示。“这是非常低效的。在C#中是否有更好的方法来实现这一点?…出于某种原因,在300X300列表循环中运行这一过程大约需要2分钟。如果我将它们转换为散列或其他方式,比较起来会更快。我认为字符串比较正在扼杀这一点。”。该部分是对Adrian评论的回应。如果大多数对象不同,那么它不会提供太多好处