起初想用SortedDictionary做游戲中的排行榜,代碼如下:
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class CustomComparer<T> : IComparer<T>
{
Func<T, T, int> mComparerFunc;
public CustomComparer(Func<T, T, int> comparer)
{
this.mComparerFunc = comparer;
}
public int Compare(T x, T y)
{
return mComparerFunc(x, y);
}
}
public class SortedDictTest : MonoBehaviour
{
SortedDictionary<string, int> mLeaderboard;
void Start()
{
mLeaderboard = new SortedDictionary<string, int>(new CustomComparer<string>((x, y) => mLeaderboard[x].CompareTo(mLeaderboard[y])));
mLeaderboard.Add("Jhon", 10);
mLeaderboard.Add("Dark", 40);
mLeaderboard.Add("Ellie", 20);
foreach (var item in mLeaderboard)
{
Debug.Log("Name: " + item.Key + " Score: " + item.Value);
}
}
}
結果就是unity死循環

當你get字典中的數值時,它會調用比較器。比較器裡又調用了字典,造成死循環
而且這種用法還有一個問題,可排序字典是對key進行排序,操作時內部有類似二分查找的機制。
在做排行榜時又要按名稱匹配,又要自動按分數排序,此時是兩套排序機制,字典內部順序混亂,查找速度反而更慢。
解決方法也是有的,使用雙字典可以解決:
public class SortedDictTest : MonoBehaviour
{
Dictionary<string, int> mScoreDict;
SortedDictionary<string, int> mLeaderboard;
void Start()
{
mScoreDict = new Dictionary<string, int>();
mLeaderboard = new SortedDictionary<string, int>(new CustomComparer<string>((x, y) => mScoreDict[x].CompareTo(mScoreDict[y])));
mScoreDict.Add("Jhon", 10);
mScoreDict.Add("Dark", 40);
mScoreDict.Add("Ellie", 20);
mLeaderboard.Add("Jhon", 10);
mLeaderboard.Add("Dark", 40);
mLeaderboard.Add("Ellie", 20);
foreach (var item in mLeaderboard)
{
Debug.Log("Name: " + item.Key + " Score: " + item.Value);
}
}
}

具體看數據量多少來權衡,直接使用List排序也未嘗不可