随机生成纸牌的类:
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--;
卡座仍会产生重复。我使用数组方法不正确吗?
答案 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();
}
没有,我们无法测试并看到它是否按预期工作(计算需要一点时间,因此这里肯定有进行优化的机会,但我希望这会有所帮助):