OrderBy忽略重音字母
  我想要一个像OrderBy()这样的方法,总是命令忽略重音字母并将它们看作非重音字符。  我已经试图覆盖OrderBy()但似乎我不能这样做,因为这是一个静态方法。 
  所以现在我想为OrderBy()创建一个自定义lambda表达式,如下所示: 
public static IOrderedEnumerable<TSource> ToOrderBy<TSource, TKey>(
    this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    if(source == null)
        return null;
    var seenKeys = new HashSet<TKey>();
    var culture = new CultureInfo("pt-PT");
    return source.OrderBy(element => seenKeys.Add(keySelector(element)), 
                          StringComparer.Create(culture, false));
} 
但是,我收到此错误:
错误2方法'System.Linq.Enumerable.OrderBy <TSource,TKey>(System.Collections.Generic.IEnumerable <TSource>,System.Func <TSource,TKey>,System.Collections.Generic.IComparer <TKey>的类型参数>)'不能从使用中推断出来。 尝试明确指定类型参数。
  似乎它不喜欢StringComparer 。  我该如何解决这个问题? 
注意:
  我已经尝试从这里使用RemoveDiacritics() ,但我不知道如何在这种情况下使用该方法。  所以我试图做这样的事情,看起来不错。 
  OrderBy将keySelector作为第一个参数。  这个keySelector应该是一个Func<string,T> 。  所以你需要一个接受一个字符串并返回一个值的方法,枚举应该被排序。 
  不幸的是,我不知道如何确定一个角色是否是一个“重音字母”。  RemoveDiacritics不适用于我的é 。 
  所以我们假设你有一个名为IsAccentedLetter的方法来确定一个字符是否是一个重音字母: 
public bool IsAccentedLetter(char c)
{
    // I'm afraid this does NOT really do the job
    return CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.NonSpacingMark;
}
所以你可以像这样排序你的列表:
string[] myStrings = getStrings(); // whereever your strings come from
var ordered = myStrings.OrderBy(s => new string(s.Select(c => 
    IsAccentedLetter(c) ? ' ' : c).ToArray()), StringComparer.Create(culture, false));
  lambda表达式接受一个字符串并返回相同的字符串,但用空格替换重音字母。 
  OrderBy现在通过这些字符串对枚举进行排序,因此“忽略”重音字母。 
  更新:如果你有一个工作方法RemoveDiacritics(string s) ,它返回带有重音字母的字符串,你可以简单地调用OrderBy : 
string[] mystrings = getStrings();
var ordered = myStrings.OrderBy(RemoveDiacritics, StringComparer.Create(culture, false));
  解决了!  我得到这个错误是因为使用StringComparer元素在OrderBy()表达式中排序,该元素需要是一个string 。 
  因此,当我知道该元素是一个字符串时,我将其转换为字符串,并使用RemoveDiacritics()方法忽略重音字母,并将它们看作非重音字符。 
public static IOrderedEnumerable<TSource> ToOrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    if(!source.SafeAny())
        return null;
    return source.OrderBy(element => Utils.RemoveDiacritics(keySelector(element).ToString()));
}
  为了garantee的RemoveDiacritics()我添加了一个工作正常HtmlDecode()线。 
public static string RemoveDiacritics(string text)
{
    if(text != null)
        text = WebUtility.HtmlDecode(text);
    string formD = text.Normalize(NormalizationForm.FormD);
    StringBuilder sb = new StringBuilder();
    foreach (char ch in formD)
    {
        UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(ch);
        if (uc != UnicodeCategory.NonSpacingMark)
        {
            sb.Append(ch);
        }
    }
    return sb.ToString().Normalize(NormalizationForm.FormC);
}
上一篇: OrderBy ignoring accented letters
下一篇: Unexpected reserved word error while testing using wallaby
