Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.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#_Extension Methods - Fatal编程技术网

C# 扩展方法未返回正确的集合

C# 扩展方法未返回正确的集合,c#,extension-methods,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]

我使用的是一个扩展方法,它洗牌一个通用列表。这很有效

    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;
    }
  }
publicstaticvoidshuffle(此IList列表)
{
RNGCryptoServiceProvider=新的RNGCryptoServiceProvider();
int n=list.Count;
而(n>1)
{
字节[]框=新字节[1];
do provider.GetBytes(框);
而(!(框[0]
我正在尝试创建另一个扩展方法,该方法将使用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;
  }
public static void GroupRandomize(此IList sourceList,int groupSize)
{
List shuffledList=新列表();
列表模板列表=新建列表();
int addCounter=0;
for(int i=0;i

如何确保无序列表正确存储到源列表中?

源列表实际上是一个局部变量。 最好
返回shuffedList

var newList = caller.GroupRandomize<T>(5) ;
var newList=caller.GroupRandomize(5);
除非您使用的是
ref
参数,否则这不会起任何作用。您可以更改方法,使其直接修改sourceList:

for(int i = 0; i < sourceList.Length; i++)
    sourceList[i] = shuffledList[i];
。。。你会说:

var list = GetList().Shuffle();

将其设置为常规方法而不是扩展,以便通过引用传递:

public static void GroupRandomize<T>(ref IList<T> sourceList, int groupSize) {
    // ... stuff
    sourceList = shuffledList;
}
publicstaticvoidgrouprandomize(参考IList sourceList,int groupSize){
//…东西
sourceList=shuffledList;
}

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

sourceList.Clear();
sourceList.AddRange( shuffledList );
编辑:

如所述,
AddRange
方法在
IList
界面中不可用


已经提出了一个实现
AddRange
将要做的事情,因此我将通过指向另一个实现
AddRange
作为
IList
的扩展方法来改进他的答案,同意,我通常会尽量避免在扩展方法中修改扩展对象的值。对于带有Microsoft NuGet软件包的.NET 4.5,您可以通过选择一个来更好地表达契约。第一个示例修改列表的内容。第二个示例不修改sourceList的内容。您“尝试”将sourceList指向的内容替换为shuffledList的赋值,但除非您使用
ref
,否则此更改仅为本地更改。执行
sourceList=shuffledList
操作时,您将本地
sourceList
变量赋值给
shuffledList
引用的对象,而不更改原始列表。这是相关的:原因与扩展方法无关。您正在修改一个参数,这对我来说是一个严重的警告(除了在方法的顶部是最琐碎的,注释很好的情况)。这是可行的,但是我会考虑通过引用传递列表,而不是仅仅返回结果列表是一个糟糕的决定。AWWW,什么可能出错?出于好奇,为什么?确实,将引用传递回去同样容易,但是您知道传递ref可能导致的问题吗?我已经读了一些关于函数式编程的书,它的优点之一似乎是不可变的,并且没有副作用。听起来不错。如果你有一个域a,它总是映射到一个新的范围B。你不改变域a本身。但是没有什么能阻止你通过引用course@FrancineDeGroodTaylor这不是一个好习惯。对象往往会被传递很多次,如果你在不需要的时候开始通过引用传递东西,你会很快陷入一个非常不稳定的局面,很多不同的方法都共享一个特定引用的同一个实例,一个看似无关紧要的赋值可能会导致各种各样的错误(很难调试)疯狂别处。AddRange()方法对IListoops不可用,我没有注意到
IList
前面的
I
。你是对的。我将改变我的答案以反映这一点。谢谢
public static void GroupRandomize<T>(ref IList<T> sourceList, int groupSize) {
    // ... stuff
    sourceList = shuffledList;
}
sourceList.Clear();
sourceList.AddRange( shuffledList );