我正在尝试使用对象的名称属性对通用对象列表进行排序。 我正在使用LINQ,以下表达式不太起作用:
var query = possibleWords.OrderBy(x => x.Name.ToLower()).ToList();
foreach (Word word in query) //possibleWords.OrderBy(word => word.Name))
{
listWords.Items.Add(word.Name);
}
如果我理解正确,“query”现在应该包含一个有序列表,如果要将某个项目添加到名为listWords的列表框中。
然而输出结果是这样的:http://screencast.com/t/s1CkkWfXD4(抱歉只能提供URL链接,因为SO似乎锁定了我的帐户,并且我不能在新账户中发布图片)。
列表框几乎按字母顺序排列,但有些例外。由于某种原因,“aa”和“aaaa”排在最后。可能的原因是什么?如何解决?
提前感谢您的回答。
根据请求进一步解释:当在Visual Studio中输入并执行此代码时:
List<Word> words = new List<Word>();
words.Add(new Word("a"));
words.Add(new Word("Calculator"));
words.Add(new Word("aaa"));
words.Add(new Word("Projects"));
words.Add(new Word("aa"));
words.Add(new Word("bb"));
words.Add(new Word("c"));
IEnumerable<Word> query = words.OrderBy(x => x.Name.ToLower()).ToList();
foreach (Word word in query)
{
Console.WriteLine(word.Name);
}
给我以下输出结果:
a
bb
c
Calculator
ccc
Projects
aa
aaa
这并没有正确排序:第一个"a"是对的,但随后的"aa"和"aaa"条目被放到了列表底部。我对字符集和编码不太了解,所以可能我在这里犯了一个初学者的错误。但如果是这样的话,我不知道是什么错误,并且我会有点困惑,为什么第一个"a"可以正确排序,但第二个和第三个"aa"和"aaa"不能!更进一步的解释-单词类别。
[Serializable()]
public class Word
{
[System.Xml.Serialization.XmlAttribute("Name")]
public string Name { get; set; }
public Word(string name)
{
Name = name;
}
public Word() { } //Parameter less constructor neccessary for serialization
}
原因和解决方法
像@Douglas建议的那样,将StringComparer.InvariantCultureIgnoreCase比较器提供给OrderBy方法可以解决问题。
进一步研究发现,使用丹麦文化(da-DK)时,FindAll和OrderBy方法(可能还有其他方法)存在问题。可能会有其他失败的方法或文化,但是da-DK文化和FindAll + OrderBy方法绝对不能正常工作。
OrderBy方法存在如本主题中描述的问题(错误排序)。 FindAll方法有一个类似的、非常奇怪的问题:假设我们有一个条目列表:a、aa、aaa和aaaa。当使用FindAll(x => x.StartsWith("a"))时,它只会返回"a",而不是aa、aaa和aaaa。如果使用StartsWith("aa"),它将正确地找到aa,以及aaa和aaaa。当使用StartWith("aaa")时,它又不会找到aaaa,只有aaa!这似乎是框架中的一个错误。
query.Count()
是否等于列表中单词的数量。同时,请确保只使用英文字符。 - Sergey BerezovskiyWord
类。 - Sergey BerezovskiyWord
类相关的代码,这才是你真正的问题所在......只需将你的代码中的Word
替换为string
,你就会发现它可以工作。 - L.B