如何用委托对C# List排序?排序仅执行一次未达预期
问题分析与解决方案
核心问题排查
- 你的比较委托仅执行一次,大概率是某次
int.Parse抛出未捕获异常导致排序流程中断。比如某个score字段不是有效整数字符串(空值、含非数字字符、格式错误等),Unity遇到未处理异常会终止当前操作,因此只完成一次比较就停了。 - 另外,
scores.Count()是LINQ扩展方法,若你使用的是List<T>,建议直接调用scores.Count属性,避免不必要的枚举开销。
修复方案
1. 用int.TryParse替代int.Parse,避免异常中断排序
改成带容错的解析逻辑,确保即使遇到无效分数也能完成排序:
void SortScores() { Debug.Log($"Sorting Scores: {scores.Count}"); scores.Sort((x, y) => { int scoreX = int.TryParse(x.score, out int valX) ? valX : 0; // 无效分数默认设为0,可按需调整规则 int scoreY = int.TryParse(y.score, out int valY) ? valY : 0; Debug.Log($"Comparing {scoreX} with {scoreY}"); return scoreX.CompareTo(scoreY); // 升序排序,要降序则改为 scoreY.CompareTo(scoreX) }); }
2. 预转换所有分数,提升效率并提前排查无效数据
若排序操作频繁,建议先把所有分数解析为int存储,避免比较时重复解析:
// 先修改结构体,新增存储解析后分数的字段 struct LeaderboardScore { public string score; public int IntScore; // 新增字段 } // 在Firebase拉取数据完成后,先批量解析分数 void ParseScores() { foreach (var item in scores) { bool isValid = int.TryParse(item.score, out int val); item.IntScore = isValid ? val : 0; // 日志记录无效分数,方便排查问题 if (!isValid) { Debug.LogWarning($"无效分数字符串: {item.score}"); } } } // 排序时直接使用预解析的IntScore void SortScores() { Debug.Log($"Sorting Scores: {scores.Count}"); scores.Sort((x, y) => x.IntScore.CompareTo(y.IntScore)); }
额外检查点
- 确认
scores是List<LeaderboardScore>类型,而非只读集合或其他不支持原地排序的类型(List<T>.Sort是原地排序,其他集合可能无此方法)。 - 检查Firebase数据拉取逻辑,确保23个元素的
score字段都被正确赋值,无空值或异常内容。
内容的提问来源于stack exchange,提问作者Lee Probert
相关产品推荐
相关产品推荐

