【问题标题】:Compare the values of properties of two objects in LINQ比较 LINQ 中两个对象的属性值
【发布时间】:2014-05-05 00:14:26
【问题描述】:

我的代码List<student> list1List<student> list2 中有两个学生对象列表。 学生对象具有以下属性。 FirstName LastName University

我有以下方法,我想使用 LINQ 比较两个列表中的对象之间的相应属性的值。我在 LINQ 中找到了一些示例,这些示例展示了如何比较整数或字符串列表中的两个值,但找不到任何可以比较列表中对象的属性值的示例。

`private CompareList(ref List<student> L1,ref List<student> L2)
 {
   // compare FirstName of L1 to L2
      ......

 }`

我该怎么做呢? 谢谢!

【问题讨论】:

  • 首先,您需要在询问 SO 之前实际尝试并实施该方法。其次,你为什么要通过引用传递你的列表?最后,您为什么觉得有必要为此使用 Linq?
  • 嗨 Ant,我想知道一种有效的方法来实现该方法,这就是我问这个问题的原因。如果不是 LINQ,那么这就是我问这个问题的原因,以便我以适当的方式实现该方法。我使用 ref 以免再次创建不必要的变量以提高效率。谢谢
  • 我认为你不明白 ref 做了什么。它不会阻止创建不必要的变量。这只是意味着,如果您要为ref 传递的变量分配一个新列表,它将更改调用代码中的引用。如果省略ref,则无法更改调用代码中的引用。无论您是否使用ref,每次调用都会在堆栈上创建一个新变量。
  • 嗨 Enigmativity,我确实了解 ref 的作用,它设置变量 L1 来引用同一个对象而不创建对象的新副本,我不需要使用 ref 关键字,但我是如果对象列表很大,请谨慎行事。
  • @Irfarino,你真的不明白ref 是什么意思。 List&lt;student&gt;(或任何 List&lt;T&gt; - 并且类型通常是 Pascal 大小写)是引用类型,这意味着它驻留在堆上,变量(或方法参数)只保存指向它的指针。当您使用 ref 时,您将指针传递给指针。你的推理对于值类型 (struct) 是有效的,这些值类型永远不应该是可变的或太大以至于你考虑将它们传递给方法作为参考,因为它的大小。

标签: linq c#-4.0


【解决方案1】:
public static bool Compare(ref List<Student> list1, ref List<Student> list2)
{
        return Enumerable.SequenceEqual(list1,list2, new MyCustomComparer());
}

public class MyCustomComparer : IEqualityComparer<Student>
{
    public bool Equals(Student x, Student y)
    {
        if (x.FirstName == y.FirstName && x.LastName == y.LastName && x.University == y.University)
            return true;
        return false;
    }

    public int GetHashCode(Student obj)
    {
        throw new NotImplementedException();
    }
}

【讨论】:

    【解决方案2】:

    你没有说你到底想检查什么,但如果你只是想知道两个集合是否相等,那么我想你可以这样检查:

    bool isAnyElementFromL1NotInL2 = L1.Select(x => x.Name).Except(L2.Select(y => y.Name)).Any();
    bool isAnyElementFromL2NotInL1 = L2.Select(x => x.Name).Except(L1.Select(y => y.Name)).Any();
    bool areL1AndL2TheSame = !isAnyElementFromL1NotInL2 && !isAnyElementFromL2NotInL1;
    

    另见this answer by Jon Skeet

    this question

    【讨论】:

    • 嗨 Lech,谢谢你的回答,我之前看到了 Jon 的回答,我拥有的列表不仅仅是一个值列表,它是一个对象列表,我想比较一下属性第一个列表中的对象与第二个列表中对象的属性,我不确定这是否是您描述的直接比较,但是我会尝试您的方法,看看它是否有效。谢谢!
    【解决方案3】:

    最好的方法是通过实现 IComparable&lt;student&gt;/IStructuralComparableIEquatable&lt;student&gt;/IStructuralEquatable 或通过创建比较器类来比较 student(类型通常为 Pascal 大小写)实现IComparaer&lt;T&gt;

    【讨论】:

    • 您好 Paulo,感谢您的回答,我在做一些研究时遇到了 IEquatable 接口,我可能会实现该接口。
    猜你喜欢
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多