C#:协助使此洗牌方法工作
我仔细研究了C#文档,还没有找到一个名为C#:协助使此洗牌方法工作,c#,C#,我仔细研究了C#文档,还没有找到一个名为Shuffle()的实际方法,但我想要一个实现,它至少看起来和感觉上类似于一个名为Shuffle()的内置方法,而且我知道我必须手动将实际逻辑组合起来,以执行随机或随机操作 这就是我学习Fisher-Yates方法的地方,这让我找到了我喜欢的手榴弹解决方案: 不幸的是,我似乎无法让这个解决方案为我工作。无论我如何配置它,最终都会出现以下错误: 错误CS1501:如果我想以这种方式维护解决方案,则方法“Shuffle”不会重载接受“0”个参数: using
Shuffle()
的实际方法,但我想要一个实现,它至少看起来和感觉上类似于一个名为Shuffle()的内置方法
,而且我知道我必须手动将实际逻辑组合起来,以执行随机或随机操作
这就是我学习Fisher-Yates方法的地方,这让我找到了我喜欢的手榴弹解决方案:
不幸的是,我似乎无法让这个解决方案为我工作。无论我如何配置它,最终都会出现以下错误:
错误CS1501:如果我想以这种方式维护解决方案,则方法“Shuffle”不会重载接受“0”个参数:
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;
}
}
我被告知洗牌不是一种方法:
错误CS1061:Type
System.Collections.Generic.List'不包含Shuffle'的定义,并且找不到类型为System.Collections.Generic.List'的扩展方法。
我知道这一点,但这对手榴弹有什么作用?除了几年的经验之外,我还缺少什么?洗牌的原型
publicstaticvoidshuffle(IList列表)
与在main
deck.Shuffle()代码>
这就是为什么会出现CS1051错误。首先修复该错误,然后它也会对您起作用。您提到的解决方案是针对实现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;
}
}
}
shuffle方法应该是一种扩展方法。将其移动到自己的静态类中。您还需要重新输入这个
关键字。再看看源答案。该方法是静态的,在一个单独的静态类中。。输入参数前面有this
关键字。您可以尝试为每个参数创建一个新的GUID,然后按GUID排序,而不是随机设置。@DmitriTrofimov它看起来不错,但性能不太好。请参阅答案:guid是唯一性的来源,而不是随机性的来源。它们是不同的东西。不要使用guid,这是有道理的。虽然string.Join
的美妙之处在于它不会在物品列表的末尾留下一个尾随的,“
。Bogdan在《手榴弹回答》中这样称呼它:products.Shuffle()
不是吗?根据OP提供的链接,它实际上应该是一个扩展方法Rufus,因此在我的Deck
类中定义这个扩展方法是我的第一个错误,所有扩展方法都必须在C中自己的类中,是的,它们必须在静态
类中定义。虽然类可以包含其他非扩展的静态
方法,但它们通常不包含。还要注意this
关键字的使用,它定义了扩展应用于的类型(该参数表示调用该方法的该类型的实例)。有关更多信息,请参阅。
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;
}
}
}
public class Deck
{
public void Shuffle()
{
Cards.Shuffle(); // This is using the extension method we created above
}
// Rest of Deck class code omitted
}