我正在使用一种扩展通用列表的扩展方法。这工作
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;
}
如何确保混洗列表正确存储到源列表中?
答案 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>
的扩展方法。