我研究了C#文档,但没有找到称为Shuffle()
的实际方法,但是我想要一个至少看起来和感觉像名为Shuffle()
的内置方法的实现。而且我知道我将不得不手动组合实际逻辑来进行混洗或随机化。
这是我了解Fisher-Yates方法的地方,这使我进入了这个特殊的职位,并得到了手榴弹支持的解决方案:
不幸的是,我似乎无法使该解决方案对我有效。无论我如何配置,我总是会遇到此错误:
error CS1501: No overload for method 'Shuffle' takes '0' arguments
,如果我想以这种方式维护解决方案:
using System;
using System.Collections.Generic;
class Program
{
public static void Main()
{
// List<Deck> deck = new List<Deck>();
Deck deck = new Deck();
deck.Shuffle();
System.Console.WriteLine(deck);
}
}
public class Deck {
public List<Card> Cards = new List<Card>();
public Deck() {
string[] ranks = { "Ace", "Two", "Three", "Four", "Five" };
string[] suits = { "Diamonds", "Hearts", "Clubs", "Spades" };
foreach (string suit in suits) {
foreach (string rank in ranks) {
Card card = new Card(rank, suit);
Cards.Add(card);
}
}
}
public override string ToString()
{
string s = "[";
foreach (var card in Cards) {
s += card.ToString() + ", ";
}
s += "]";
return s;
}
private static Random rng = new Random();
public static void Shuffle<T>(IList<T> list)
{
int n = list.Count;
while (n > 1) {
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
public class Card {
// properties
public string suit { get; set; }
public string rank { get; set; }
public override string ToString()
{
return $"{rank} of {suit}";
}
public Card(string rank, string suit){
//initializations
this.rank = rank;
this.suit = suit;
}
}
它具有使用内置方法的外观,但是该错误告诉我我需要将某些内容传递给Shuffle()
,因为我这样声明:public static void Shuffle<T>(IList<T> list)
,并且没有无论我尝试传递给它什么,都会导致另一个错误。
那么,如果我同意这一点:
class Program
{
public static void Main()
{
List<Deck> deck = new List<Deck>();
// Deck deck = new Deck();
deck.Shuffle();
System.Console.WriteLine(deck);
}
}
我被告知Shuffle不是一种方法:
error CS1061: Type
System.Collections.Generic.List'不包含类型Shuffle' and no extension method
的{{1}} Shuffle'的定义
我知道这一点,但是手榴弹如何工作?除了几年的经验,我还缺少什么?
答案 0 :(得分:1)
Shuffle
的原型
public static void Shuffle<T>(IList<T> list)
与您在main
中的呼叫方式不同
deck.Shuffle();
这就是为什么出现 CS1051 错误的原因。首先修复该错误,然后对您也适用。
答案 1 :(得分:0)
您引用的解决方案是针对实现IList
的对象的扩展方法。扩展方法必须驻留在单独的类中,因此您所需要做的就是在名称空间中添加一个新类来容纳扩展方法。
public class Deck
{
// Implementation omitted
}
public static class Extensions
{
private static Random rng = new Random();
// This extension method is now available to any class that implements 'IList'
public static void Shuffle<T>(this IList<T> list)
{
var currentIndex = list.Count;
while (currentIndex > 1)
{
var swapIndex = rnd.Next(currentIndex--);
var value = list[swapIndex];
list[swapIndex] = list[currentIndex];
list[currentIndex] = value;
}
}
}
现在,您可以在Deck
类的Shuffle
类中使用此方法。由于Cards
是List<Card>
,并且List<T>
实现了IList
,因此当您键入
Cards.
,Shuffle
现在将出现在智能感知中:
public class Deck
{
public void Shuffle()
{
Cards.Shuffle(); // This is using the extension method we created above
}
// Rest of Deck class code omitted
}