C# 列表';s使用Lambda进行排序?

C# 列表';s使用Lambda进行排序?,c#,sorting,lambda,C#,Sorting,Lambda,我试图做的是在retVal中遍历country集合,并按名称对每个进行排序。层次结构如下: retVal[index].StateProvinces.ToList()[index].Name = ""; 因此,它是国家对象->国家的集合,每个国家都有一个name属性,并延迟加载它,根据stateID将国家对象按顺序抛出 这行代码有什么问题(尽管我猜我在试图滥用sort方法,但为什么会这样) retVal的类型为IList 为x=>x.Name提供了错误: Delegate 'System.Co

我试图做的是在
retVal
中遍历country集合,并按
名称对每个
进行排序。层次结构如下:

retVal[index].StateProvinces.ToList()[index].Name = "";
因此,它是国家对象->国家的集合,每个国家都有一个name属性,并延迟加载它,根据stateID将国家对象按顺序抛出

这行代码有什么问题(尽管我猜我在试图滥用sort方法,但为什么会这样)

retVal
的类型为
IList

x=>x.Name
提供了错误:

Delegate 'System.Comparison<Country>' does not take 1 arguments
委托“System.Comparison”不接受1个参数

正如错误所说,
比较
采用两个参数,而不是一个,您需要这样的参数:

retVal[0].StateProvinces.ToList().Sort((x,y) => x.Name.CompareTo(y.Name));

正如error所说,
比较
采用两个参数,而不是一个参数,您需要这样的参数:

retVal[0].StateProvinces.ToList().Sort((x,y) => x.Name.CompareTo(y.Name));

比较
委托是代表比较而非投影的委托。也就是说,它需要两个对象,结果表明哪个对象“更小”。您试图提供一个投影,或一个对象到另一个对象的转换

要基于
Name
为这两个对象编写比较,您需要编写如下内容:

(a,b) => string.Compare(a.Name, b.Name);
您还可以编写一个单独的方法来对使用投影而不是比较器的列表进行排序,这样您就不必为每次调用
sort

//TODO come up with a better name, but it still has to be different from `Sort`
public static void ProjectionSort<T, TKey>(
    this List<T> list,
    Func<T, TKey> selector,
    Comparer<TKey> comparer)
{
    comparer = comparer ?? Comparer<TKey>.Default;
    list.Sort((a, b) => comparer.Compare(selector(a), selector(b)));
}
//TODO要想出一个更好的名称,但它必须与'Sort'不同`
公共静态无效投影排序(
这个名单,,
函数选择器,
比较器(比较器)
{
比较器=比较器??比较器。默认值;
list.Sort((a,b)=>comparer.Compare(选择器(a),选择器(b));
}

比较
委托是代表比较而非投影的委托。也就是说,它需要两个对象,结果表明哪个对象“更小”。您试图提供一个投影,或一个对象到另一个对象的转换

要基于
Name
为这两个对象编写比较,您需要编写如下内容:

(a,b) => string.Compare(a.Name, b.Name);
您还可以编写一个单独的方法来对使用投影而不是比较器的列表进行排序,这样您就不必为每次调用
sort

//TODO come up with a better name, but it still has to be different from `Sort`
public static void ProjectionSort<T, TKey>(
    this List<T> list,
    Func<T, TKey> selector,
    Comparer<TKey> comparer)
{
    comparer = comparer ?? Comparer<TKey>.Default;
    list.Sort((a, b) => comparer.Compare(selector(a), selector(b)));
}
//TODO要想出一个更好的名称,但它必须与'Sort'不同`
公共静态无效投影排序(
这个名单,,
函数选择器,
比较器(比较器)
{
比较器=比较器??比较器。默认值;
list.Sort((a,b)=>comparer.Compare(选择器(a),选择器(b));
}

好的。。昨晚我对这个问题感到非常沮丧,今天早上我意识到真正的问题是,Sort不存在。您需要调用的“排序”集合的方法是.OrderBy


希望这能帮助某人不要把头发都拔出来。

好的。。昨晚我对这个问题感到非常沮丧,今天早上我意识到真正的问题是,Sort不存在。您需要调用的“排序”集合的方法是.OrderBy


希望这能帮助某人不要把头发都拔出来。

.OrderBy(x=>x.Name)
.OrderBy(x=>x.Name)
如果任何名称为
null
,则此选项将中断。如果任何名称为
null
,则此选项将中断。这在某种程度上起作用。我可以看到它实际上在进行比较,但实际上并没有将已排序的对象存储回retVal[index].stateProvisions。我做错了什么?@metalfenix您将所有项目从序列中拉出来,创建一个新列表来存储数据,对列表进行排序,然后将该列表丢弃,而不做任何处理。如果你想将结果存储在那个属性中,你需要显式地将结果存储回那个属性中。啊,我想我明白了。我原以为它不会返回任何东西,因为VS中的返回类型显示为“void”。结果还表明,在我今天发现的一段代码中,有一些疯狂的胡言乱语,我以前在项目架构的深处没有看到过。谢谢你的建议,这很有效。我可以看到它实际上在进行比较,但实际上并没有将已排序的对象存储回retVal[index].stateProvisions。我做错了什么?@metalfenix您将所有项目从序列中拉出来,创建一个新列表来存储数据,对列表进行排序,然后将该列表丢弃,而不做任何处理。如果你想将结果存储在那个属性中,你需要显式地将结果存储回那个属性中。啊,我想我明白了。我原以为它不会返回任何东西,因为VS中的返回类型显示为“void”。结果还表明,在我今天发现的一段代码中,有一些疯狂的胡言乱语,我以前在项目架构的深处没有看到过。谢谢你的建议。