ArgumentException: элемент уже существует в SortedSet

У меня возникли проблемы с использованием SortedList в C# (я работаю над Unity 5.0.3 с Visual Studio 2015). У меня есть два класса ScoreKey и Score. ScoreKey реализует IComparable.

Но когда я пытаюсь добавить запись в SortedList, я получаю сообщение об ошибке

ArgumentException: element already exists
System.Collections.Generic.SortedList`2[ScoreKey,Score].PutImpl (.ScoreKey key, .Score value, Boolean overwrite)

Я не могу понять, почему я получаю эту ошибку. Я использую экземпляры класса в качестве ключа, поэтому у меня нет шансов иметь один и тот же ключ, верно? Вот код.

Определения классов:

public class ScoreKey : IComparable
{
    public uint val;
    public uint timestamp;
    public int CompareTo(object obj)
    {
        ScoreKey s2 = obj as ScoreKey;
        if (s2.val == val)
        {
            return timestamp.CompareTo(s2.timestamp);
        }
        return val.CompareTo(s2.val);
    }
}
[System.Serializable]
public class Score
{

    public ScoreKey key;
    public uint val
    {
        get { return key.val; }
    }
    string user;
    public uint timestamp
    {
        get
        {
            return key.timestamp;
        }
    }
    public Score(string _user, uint _score)
    {
        key = new ScoreKey();
        key.timestamp = GetUTCTime();
        user = _user;
        key.val = _score;
    }
}

Тестовый код:

SortedList<ScoreKey, Score> scoreList = new SortedList<ScoreKey, Score>();
Score[] scores = {
    new Score("Bishal", 230),
    new Score("Bishal", 3456),
    new Score("Bishal", 230),
    new Score("Bishal", 123),
    new Score("Bishal", 86),
    new Score("Bishal", 4221)
};
for(int i = 0; i< scores.Length; i++)
{
    Debug.Log(scores[i].pretty);

    scoreList.Add(scores[i].key, scores[i]);
}

ИЗМЕНИТЬ:

** Функция GetUTCTime: **

public static uint GetUTCTime()
{
   return (uint)(System.DateTime.UtcNow.Subtract(new System.DateTime(1970, 1, 1))).TotalSeconds;
}

person bytestorm    schedule 21.02.2016    source источник


Ответы (1)


Я не знаю, что делает метод GetUTCTime, но, если предположить, что он возвращает некоторую меру текущего времени, существует высокая вероятность того, что он вернет одно и то же значение несколько раз подряд.

Таким образом, у вас будет дублирующийся ключ, потому что второе поле val равно 230 в двух элементах:

new Score("Bishal", 230),
new Score("Bishal", 3456),
new Score("Bishal", 230),

Если вы не хотите генерировать уникальную метку времени, такую ​​как ключи, вы можете проверить Как убедиться, что отметка времени всегда уникальна?.

person Eugene Podskal    schedule 21.02.2016
comment
Я добавил определение метода getutctime. И val не будет 0, проверьте конструктор класса Score. - person bytestorm; 21.02.2016
comment
Также в текущем примере временные метки не будут проверяться, так как ни один из результатов не равен - person bytestorm; 21.02.2016
comment
@bytestorm С каких пор 230 не равно 230? И поскольку вы конвертируете метку времени в целочисленное значение, если два объекта создаются в течение одной и той же секунды, они будут иметь одну и ту же метку времени. - person Dennis_E; 21.02.2016
comment
@Dennis_E, извините, это была проблема. Виноват. - person bytestorm; 21.02.2016
comment
Да, мне нужно сделать временные метки уникальными. Это должно решить остальные проблемы. - person bytestorm; 21.02.2016