Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:协助使此洗牌方法工作_C# - Fatal编程技术网

C#:协助使此洗牌方法工作

C#:协助使此洗牌方法工作,c#,C#,我仔细研究了C#文档,还没有找到一个名为Shuffle()的实际方法,但我想要一个实现,它至少看起来和感觉上类似于一个名为Shuffle()的内置方法,而且我知道我必须手动将实际逻辑组合起来,以执行随机或随机操作 这就是我学习Fisher-Yates方法的地方,这让我找到了我喜欢的手榴弹解决方案: 不幸的是,我似乎无法让这个解决方案为我工作。无论我如何配置它,最终都会出现以下错误: 错误CS1501:如果我想以这种方式维护解决方案,则方法“Shuffle”不会重载接受“0”个参数: using

我仔细研究了C#文档,还没有找到一个名为
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
}