Я добавляю удаленные устройства в список, когда они сообщают о себе по сети. Я хочу добавить устройство в список только в том случае, если оно не было добавлено ранее.
Объявления проходят через прослушиватель асинхронных сокетов, поэтому код для добавления устройства можно запускать в нескольких потоках. Я не уверен, что делаю не так, но что бы я ни делал, я получаю дубликаты. Вот что у меня сейчас есть .....
lock (_remoteDevicesLock)
{
RemoteDevice rDevice = (from d in _remoteDevices
where d.UUID.Trim().Equals(notifyMessage.UUID.Trim(), StringComparison.OrdinalIgnoreCase)
select d).FirstOrDefault();
if (rDevice != null)
{
//Update Device.....
}
else
{
//Create A New Remote Device
rDevice = new RemoteDevice(notifyMessage.UUID);
_remoteDevices.Add(rDevice);
}
}
RemoteDevice
?Ответы:
Если в ваших требованиях не должно быть дубликатов, вы должны использовать HashSet .
HashSet.Add вернет false, если элемент уже существует (если это даже важно для вас).
Вы можете использовать конструктор, на который @pstrjds ссылается ниже (или здесь ), чтобы определить оператор равенства, или вам нужно будет реализовать методы равенства в
RemoteDevice
(GetHashCode
&Equals
).источник
List<T>
), тогда HashSet не работает.ConcurrentSet
класса, к сожалению. Однако существуетConcurrentDictionary
класс, поэтому вы можете использовать его, хранить свои значения в качестве ключей и просто сохранятьnull
значения.//HashSet allows only the unique values to the list HashSet<int> uniqueList = new HashSet<int>(); var a = uniqueList.Add(1); var b = uniqueList.Add(2); var c = uniqueList.Add(3); var d = uniqueList.Add(2); // should not be added to the list but will not crash the app //Dictionary allows only the unique Keys to the list, Values can be repeated Dictionary<int, string> dict = new Dictionary<int, string>(); dict.Add(1,"Happy"); dict.Add(2, "Smile"); dict.Add(3, "Happy"); dict.Add(2, "Sad"); // should be failed // Run time error "An item with the same key has already been added." App will crash //Dictionary allows only the unique Keys to the list, Values can be repeated Dictionary<string, int> dictRev = new Dictionary<string, int>(); dictRev.Add("Happy", 1); dictRev.Add("Smile", 2); dictRev.Add("Happy", 3); // should be failed // Run time error "An item with the same key has already been added." App will crash dictRev.Add("Sad", 2);
источник
Точно так же, как принятый ответ говорит, что у HashSet нет порядка. Если порядок важен, вы можете продолжать использовать список и проверять, содержит ли он элемент, прежде чем добавлять его.
if (_remoteDevices.Contains(rDevice)) _remoteDevices.Add(rDevice);
Выполнение List.Contains () для пользовательского класса / объекта требует реализации
IEquatable<T>
в пользовательском классе или переопределенияEquals
. Также неплохо реализоватьGetHashCode
в классе. Это согласно документации на https://msdn.microsoft.com/en-us/library/ms224763.aspxpublic class RemoteDevice: IEquatable<RemoteDevice> { private readonly int id; public RemoteDevice(int uuid) { id = id } public int GetId { get { return id; } } // ... public bool Equals(RemoteDevice other) { if (this.GetId == other.GetId) return true; else return false; } public override int GetHashCode() { return id; } }
источник