我正在尝试使用 objects Name 属性对对象的通用列表进行排序。我正在使用 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);
}
如果我理解正确,“查询”现在应该包含一个有序项目的列表,并且项目应该添加到名为 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”却不是!
进一步阐述 - Word 类
[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!这似乎是框架中的一个错误。