wake-up-neo.net

Nur eindeutiges Element zur Liste hinzufügen

Ich füge entfernte Geräte zu einer Liste hinzu, während sie sich im Netzwerk anmelden. Ich möchte das Gerät nur zur Liste hinzufügen, wenn es noch nicht hinzugefügt wurde. 

Die Ankündigungen stoßen auf einen asynchronen Socket-Listener, sodass der Code zum Hinzufügen eines Geräts auf mehreren Threads ausgeführt werden kann. Ich bin mir nicht sicher, was ich falsch mache, aber egal was ich versuche, ende ich mit Duplikationen. Hier ist was ich momentan habe .....

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);
     }
}
57
Oli

Wenn Ihre Anforderungen keine Duplikate enthalten sollen, sollten Sie ein HashSet verwenden.

HashSet.Add gibt false zurück, wenn das Element bereits vorhanden ist (falls dies für Sie sogar von Bedeutung ist).

Sie können den Konstruktor verwenden, mit dem @pstrjds unten (oder hier ) verlinkt, um den Gleichheitsoperator zu definieren, oder Sie müssen die Gleichheitsmethoden in RemoteDevice (GetHashCode & Equals) implementieren.

116
Austin Salonen
//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);
12

Genau wie die akzeptierte Antwort besagt, dass ein HashSet keine Bestellung hat. Wenn die Reihenfolge wichtig ist, können Sie eine Liste weiterhin verwenden und prüfen, ob sie den Artikel enthält, bevor Sie sie hinzufügen.

if (_remoteDevices.Contains(rDevice))
    _remoteDevices.Add(rDevice);

Das Ausführen von List.Contains () für eine benutzerdefinierte Klasse/ein Objekt erfordert die Implementierung von IEquatable<T> für die benutzerdefinierte Klasse oder das Überschreiben der Equals. Es ist eine gute Idee, auch GetHashCode in der Klasse zu implementieren. Dies ist in der Dokumentation unter https://msdn.Microsoft.com/de-de/library/ms224763.aspx angegeben

public 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;
    }
}
6
Luke Eckley

Kann als Erweiterungsmethode geschrieben werden, um Allgemeingültigkeit zu erhalten, und Sie können optional einen benutzerdefinierten Vergleicher übergeben ...

/// <summary>
/// Generates a new list with only distinct items preserving original ordering.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="comparer"></param>
/// <returns></returns>
public static IList<T> ToUniqueList<T>(this IList<T> list, IEqualityComparer<T> comparer = null)
{
    bool Contains(T x) => comparer == null ? list.Contains(x) : list.Contains(x, comparer);

    return list.Where(entity => !Contains(entity)).ToList();
}
1
Paul Hatcher