簡體   English   中英

<arrayname>.Contains 方法總是返回 false

[英]<arrayname>.Contains method always returns false

隨機生成撲克牌的類:

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--; 

甲板仍然產生重復。 我是否錯誤地使用了數組方法?

您正在嘗試檢查 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);
    }
}

實際上,您在數組上沒有Contains方法,但例如在List上有它。 所以你的實際代碼不應該編譯。 然而,我們可以保留數組並使用方法擴展,而不是使用 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 這是告訴框架我們想要使用我們當前定義的新方法擴展 Card[] 類型的方式,稱為Contains。

在我們使用Array.Find方法的方法中,我們在MSDN 中定義如下

搜索與指定謂詞定義的條件匹配的元素,並返回整個 Array 中的第一次出現。

為了比較,我們還需要使 Card 的字段可訪問,因此讓我們更改它們的可見性,並為它們定義gettersetter 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();
}

不,我們可以測試並查看它是否按預期工作(計算需要一點時間,因此這里肯定有優化的機會,但我希望這會有所幫助):

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM