[英]<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 的字段可訪問,因此讓我們更改它們的可見性,並為它們定義getter和setter 。 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.