Linq OrderBy不对列表排序< T>,如何对列表排序?

suzh9iv8  于 2022-12-06  发布在  其他
关注(0)|答案(5)|浏览(177)

OrderBy子句有问题,对排序没有任何影响。我已经在调试器中完成了这个过程,并确保这是一个代码的排序行被命中的情况,并在它之后检查结果,没有应用order by。

public static IEnumerable<DDLOptions<TValueType>> GetDDLOptionsViewModel<TClass, TValueType>(
            IEnumerable<TClass> list, 
            Func<TClass, TValueType> value, 
            Func<TClass, string> displayText,
            bool sort = true
        )
        {
            List<DDLOptions<TValueType>> ddlOptions;

            ddlOptions = list.Select(
                l => new DDLOptions<TValueType>
                        {
                            Value = value(l),
                            DisplayText = displayText(l)
                        }
                    ).ToList();  <========== Works if I put the Order By here.

            if (sort)
            {
                ddlOptions.OrderBy(l => l.DisplayText); <===== Does NOT work here.
            }

            return ddlOptions;
        }
kupeojn6

kupeojn61#

OrderBy * 返回 * 将执行排序的查询:它不会修改原始列表(而类似List<T>.Sort的内容会修改原始列表)
请尝试以下内容:

ddlOptions = ddlOptions.OrderBy(l => l.DisplayText).ToList();

您可能希望处理ddlOptions的类型,或者在哪里/如何返回数据,因为我们正在执行可能不必要的额外ToList,但无论如何,这对本例来说可能是一个次要/非问题。
请注意,这同样适用于其他LINQ函数,如GroupBy、Distinct、Concat -所有函数都返回结果,而不是修改源集合。

mccptt67

mccptt672#

试试看:

if (sort)
{
    ddlOptions = ddlOptions.OrderBy(l => l.DisplayText); <===== Should work now.
}
pes8fvy9

pes8fvy93#

正如其他人所说,你需要将OrderBy的结果赋给某个对象,因为它不会改变它所作用的序列。最简单的方法是将ddlOptions变成IEnumerable而不是List,这样你就可以将结果赋给它。也不需要对select的ToList调用:

public static IEnumerable<DDLOptions<TValueType>> GetDDLOptionsViewModel<TClass, TValueType>(
        IEnumerable<TClass> list,
        Func<TClass, TValueType> value,
        Func<TClass, string> displayText,
        bool sort = true
    )
{
    IEnumerable<DDLOptions<TValueType>> ddlOptions;

    ddlOptions = list.Select(
        l => new DDLOptions<TValueType>
                {
                    Value = value(l),
                    DisplayText = displayText(l)
                }
            );

    if (sort)
    {
        ddlOptions = ddlOptions.OrderBy(l => l.DisplayText);
    }

    return ddlOptions;
}

注意,这个版本的方法将使用延迟执行,因此在迭代序列之前不会真正执行Select/OrderBy。如果不想这样做,可以在return行上添加ToList

4jb9z9bj

4jb9z9bj4#

您需要键入:

ddlOptions = ddlOptions.OrderBy(l => l.DisplayText);
dly7yett

dly7yett5#

OrderBy不会对List<T>或任何其他IEnumerable<T>进行排序。它会产生一个新的已排序的IEnumerable<T>。因此,调用ddlOptions.OrderBy(...)不会修改ddlOptions
如果你有一个List<T>并希望对其进行排序,你可以使用Sort方法--特别是将Comparison<T>作为参数的重载。这实际上是对列表进行排序,而不是返回一个新的IEnumerable
Comparison<T>是代表函式的委派(Delegate),这个函式会接受T中的两个,如果第一个“小于”第二个,则传回负数;如果第一个“大于”第二个,则传回正数;如果其中一个不是排在另一个之前或之后,则传回零。
在这种情况下,您不必记住这一点。相反,您可以执行以下操作:

ddlOptions.Sort((x, y) => string.CompareOrdinal(x.DisplayText, y.DisplayText));

您正在传入一个函数,该函数接受列表中的两个项,并返回它们的DisplayText属性的比较结果,该结果将为负、0或正。
有时我们使用OrderBy * 是因为 * 它不会修改原始列表。但是如果修改列表 * 是 * 我们想要的,那么我们可以使用Sort

相关问题