<arrayname> .contains方法总是返回false

时间:2019-12-31 04:55:30

标签: c# arrays class

随机生成纸牌的类:

class Card
{
    private string face;
    private string suit;

    //Constructor
    public Card()
    {
        string[] faceArray = {"Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven", "Eight"
        , "Nine", "Ten", "Jack", "Queen", "King"};
        string[] suitArray = { "Clubs", "Hearts", "Spades", "Diamonds" };

        Random rand = new Random();
        face = faceArray[rand.Next(0, 13)];
        Thread.Sleep(150);
        Random dand = new Random();
        suit = suitArray[dand.Next(0, 4)];
    }
    //Method face of suit
    public override string ToString()
    {
        return face + " of " + suit;
    }
}

我认为这可以正常工作,但这是问题所在:

class DeckOfCards
{
    private Card[] deck = new Card[52];

    //constructor fills deck with unique cards
    public DeckOfCards()
    {
        for (int i = 0; i < 52; i++)
        {
            Card tempCard = new Card();
            if (deck.Contains(tempCard))
                 i--; 
            else               
                 deck[i] = tempCard; 
        }
    }
}

即使我有:

if (deck.Contains(tempCard))
                     i--; 

卡座仍会产生重复。我使用数组方法不正确吗?

2 个答案:

答案 0 :(得分:1)

您正在尝试检查Card对象。 因此,它将使用该类的.Equals()方法。

请使用您的业务逻辑覆盖Card类的Equals()方法。 然后它将按您期望的那样工作。

class Card
{
    private string face;
    private string suit;

    //
    // your other methods
    //

    public override bool Equals(object obj)
    {
        var item = obj as Card;

        if (item == null)
        {
           return false;
        }

        return this.face.Equals(item.face) && this.suit.Equals(item.suit);
    }
}

答案 1 :(得分:0)

实际上,您在数组上没有Contains方法,但是在List中有它。因此,您的实际代码不应编译。但是,除了使用列表之外,我们还可以保留数组并使用方法扩展。方法扩展是一种很酷的方法,可以使用未定义类的方法来扩展类,但这些方法在特定上下文中可能有用。因此,让我们在一副纸牌上添加一个Contains方法。

我们可以通过以下方式做到这一点:

public static class CardFinder
    {
        public static bool Contains(this Card[] deck, Card card)
        {
            if (deck == null)
                return false;

            Card c = Array.Find(deck, c => c != null && c.face.Equals(card.face) && c.suit.Equals(card.suit));

            return c != null;
        }
    }

语法在这里特别。首先,该类应为静态,并且我们可以注意到在类型为Card[]的第一个参数之前,存在关键字this 。这就是告诉框架我们要使用我们当前定义的名为Contains的新方法扩展Card []类型的方法。

在我们使用Array.Find方法的方法中,我们在MSDN中定义如下:

  

搜索与指定谓词定义的条件匹配的元素,并返回整个Array中的第一个匹配项。

为了进行比较,我们还需要使Card的字段可访问,因此让我们更改其可见性,并为它们定义 getters setters 。 Card类的开头将如下所示(其余部分保持不变)

public class Card
{
     public string face { get; set; }
     public string suit { get; set; }

     // Rest of code here ...
}

DeckOfCards类也不需要更改,但是为了打印商品,我已经覆盖了它的ToString方法,如下所示:

public override string ToString()
{
   StringBuilder builder = new StringBuilder();
   foreach (var card in deck)
      builder.Append(card.ToString() + "\n");
   return builder.ToString();
}

没有,我们无法测试并看到它是否按预期工作(计算需要一点时间,因此这里肯定有进行优化的机会,但我希望这会有所帮助):

enter image description here