Estoy agregando dispositivos remotos a una lista a medida que se anuncian en la red. Solo quiero agregar el dispositivo a la lista si no se ha agregado previamente.
Los anuncios llegan a través de un detector de socket asíncrono, por lo que el código para agregar un dispositivo se puede ejecutar en varios subprocesos. No estoy seguro de qué estoy haciendo mal, pero no importa lo que intente, termino con duplicaciones. Esto es lo que tengo actualmente ...
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
?Respuestas:
Si sus requisitos son no tener duplicados, debe utilizar un HashSet .
HashSet.Add devolverá falso cuando el elemento ya existe (si eso te importa).
Puede utilizar el constructor que @pstrjds enlaza a continuación (o aquí ) para definir el operador de igualdad o deberá implementar los métodos de igualdad en
RemoteDevice
(GetHashCode
&Equals
).fuente
List<T>
), HashSet no funciona bien.ConcurrentSet
Desafortunadamente, no hay clase. Sin embargo, hay unaConcurrentDictionary
clase, por lo que puede usarla, almacenar sus valores como claves y simplemente almacenarnull
los valores.//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);
fuente
Al igual que la respuesta aceptada dice que un HashSet no tiene un pedido. Si el orden es importante, puede continuar usando una Lista y verificar si contiene el artículo antes de agregarlo.
if (_remoteDevices.Contains(rDevice)) _remoteDevices.Add(rDevice);
Realizar List.Contains () en una clase / objeto personalizado requiere implementarlo
IEquatable<T>
en la clase personalizada o anular elEquals
. Es una buena idea implementar tambiénGetHashCode
en la clase. Esto es por la documentación en 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; } }
fuente