扩展方法不返回正确的集合

时间:2014-06-19 17:32:50

标签: c# extension-methods

我正在使用一种扩展通用列表的扩展方法。这工作

    public static void Shuffle<T>(this IList<T> list)
  {
    RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
    int n = list.Count;
    while (n > 1)
    {
      byte[] box = new byte[1];
      do provider.GetBytes(box);
      while (!(box[0] < n * (Byte.MaxValue / n)));
      int k = (box[0] % n);
      n--;
      T value = list[k];
      list[k] = list[n];
      list[n] = value;
    }
  }

我正在尝试创建另一个使用Shuffle()的扩展方法,但是会根据定义的组大小将组中的项目分组。调试扩展方法时,此方法似乎有效,但调用代码中的源列表仍包含扩展调用后的原始列表:

    public static void GroupRandomize<T>(this IList<T> sourceList, int groupSize)
  {
    List<T> shuffledList = new List<T>();
    List<T> tempList = new List<T>();
    int addCounter = 0;
    for (int i = 0; i < sourceList.Count; i++)
    {
      tempList.Add(sourceList[i]);
      // if we've built a full group, or we're done processing the entire list
      if ((addCounter == groupSize - 1) || (i == sourceList.Count - 1))
      {
        tempList.Shuffle();
        shuffledList.AddRange(tempList);
        tempList.Clear();
        addCounter = 0;
      }
      else
      {
        addCounter++;
      }
    }
    sourceList = shuffledList;
  }

如何确保混洗列表正确存储到源列表中?

4 个答案:

答案 0 :(得分:6)

sourceList实际上是一个局部变量。 可能会更好return shuffedList;

var newList = caller.GroupRandomize<T>(5) ;

答案 1 :(得分:0)

sourceList = shuffledList;

除非您使用ref参数,否则无效。您可以更改您的方法,以便它直接修改sourceList:

for(int i = 0; i < sourceList.Length; i++)
    sourceList[i] = shuffledList[i];

但我建议您更改方法,以便扩展方法返回新的,随机播放的列表,保留原始列表的完整性。所以而不是:

var list = GetList();
list.Shuffle();

...你会说:

var list = GetList().Shuffle();

答案 2 :(得分:0)

将它设为常规方法而不是扩展名,以便您可以通过引用传递它:

public static void GroupRandomize<T>(ref IList<T> sourceList, int groupSize) {
    // ... stuff
    sourceList = shuffledList;
}

答案 3 :(得分:0)

或者,如果您不想更改方法的标题,可以执行以下操作:

sourceList.Clear();
sourceList.AddRange( shuffledList );

修改

正如bperniciaro所述,AddRange界面中未提供IList<T>方法。

StriplingWarrior已经建议执行AddRange会执行的操作,因此我只需通过answer指向另一个hvostt来改善他的答案,实现AddRange作为IList<T>的扩展方法。