使用LINQ C#的Property的唯一对象

时间:2011-09-17 21:56:35

标签: c# linq

我希望使用C#中的LINQ从列表中检索唯一项。 我有一个班级甲板,有一个属性卡,这是卡的列表。此外,班级卡还有套房式套房。我想要检索卡片列表中的所有套件项目,但只能查看独特的套件。我试过的代码是:

List<Suite> GetSuiteByCards(List<Card> cards)
    {
        List<Suite> list = cards.Select(c => c.Suite).Distinct().ToList();
        return list;
    }

如果我没弄错的话,这应该从卡片列表中检索所有独特的套房。但是,以下测试失败

// Creating test cards
Card a = new Card(suite="spade", value="ace");
Card b = new Card(suite="spade", value="king");
List<Card> cards = new List<Card>(2) {a, b}; 

// Creating deck of cards
Deck d = new Deck(cards);

以上代码创建了一副小卡片(2张卡片),具有相同的套件。因此,以下代码应该评估为true:

d.Suites.Count == 1

除了我得到:

d.Suites.Count == 2

我已经省略了一些代码,但我认为它不相关。如果我用完整的牌组(即52张牌)运行代码,我会得到4个独特的套房,如预期的那样;因此我感到非常困惑。

我已经通过扩展方法解决了这个问题,但我想知道是否有一种简单的方法可以通过LINQ来实现。

1 个答案:

答案 0 :(得分:3)

  

班级卡有套房式套房

心灵调试开启。我猜测Suite是引用类型,并且您没有覆盖Object.EqualsObject.GetHashCode

您需要覆盖Object.Equals的{​​{1}}和Object.GetHashCode。如果您未提供Suite的实施,则Distinct会使用EqualityComparer<Suite>.DefaultIEqualityComparer<Suite>返回的实施使用EqualityComparer<Suite>.DefaultObject.Equals。因此,如果您不重写这些,那么实现返回模型引用相等(和引用的哈希代码)。

或者,实现Object.GetHashCode以不通过引用相等性进行比较,并将实例传递给Enumerable.Distinct<TSource>(this IEnumerable<TSource>, IEqualityComparer<TSource>)

  

我已经省略了一些代码,但我认为它不相关。如果我用完整的牌组(即52张牌)运行代码,我会得到4个独特的套房,如预期的那样;因此我感到非常困惑。

这有点相关,但让我猜一下发生了什么。在上面的代码中,完整列表可能更像是:

IEqualityComparer<Suite>

所以在这里你要创建两个代表黑桃的Card a = new Card(new Suite("spade"), new Value("ace")); Card b = new Card(new Suite("spade"), new Value("king")); List<Card> cards = new List<Card>(2) {a, b}; 个实例。但是,这两个实例不会相等,因为它们是不同的实例,并且您没有覆盖Suite(和Equals必要)。

然而,就52张牌的情况而言,我打赌你做了这样的事情:

GetHashCode

然后

List<Suite> suites = new List<Suite>() suites {
    new Suite("spade"),
    new Suite("heart"),
    new Suite("club"),
    new Suite("diamond")
};

List<Value> values = new List<Value>() values {
    new Value("ace"),
    new Value("king"),
    // etc.
};

现在代表空格的所有卡片都与var deck = from suite in suites from value in values select new Card(suite, value); 共享相同的引用,因此Suite也可以。

顺便说一句,我不会将套装和值建模为参考类型。它们确实是价值类型。心是一颗心,这就是它的身份。它的身份不是由谁来定义,而是由它是什么来定义。

这样就可以避免整个问题的开始,因为值类型的默认相等运算符是值相等。