C#:协助使这种随机播放方法有效

时间:2019-06-14 15:39:26

标签: c#

我研究了C#文档,但没有找到称为Shuffle()的实际方法,但是我想要一个至少看起来和感觉像名为Shuffle()的内置方法的实现。而且我知道我将不得不手动组合实际逻辑来进行混洗或随机化。

这是我了解Fisher-Yates方法的地方,这使我进入了这个特殊的职位,并得到了手榴弹支持的解决方案:

Randomize a List<T>

不幸的是,我似乎无法使该解决方案对我有效。无论我如何配置,我总是会遇到此错误:

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'的定义

我知道这一点,但是手榴弹如何工作?除了几年的经验,我还缺少什么?

2 个答案:

答案 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类中使用此方法。由于CardsList<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
}