仅将唯一项添加到列表

时间:2012-11-21 16:51:44

标签: c# .net c#-4.0

我正在通过网络宣布自己将远程设备添加到列表中。我只想将设备添加到列表中,如果之前没有添加过的话。

通知是通过异步套接字侦听器发生的,因此添加设备的代码可以在多个线程上运行。我不确定我做错了什么但没有我尝试的东西我最终得到重复。这就是我现在拥有的......

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

4 个答案:

答案 0 :(得分:123)

如果您的要求不重复,则应使用HashSet

当项目已经存在时,

HashSet.Add将返回 false (如果这对你很重要)。

您可以使用@pstrjds链接到下面(或here)的构造函数来定义相等运算符,或者您需要在RemoteDeviceGetHashCode&中实现相等方法; Equals)。

答案 1 :(得分:13)

//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);

答案 2 :(得分:6)

就像接受的答案说HashSet没有订单一样。如果订单很重要,您可以继续使用列表并在添加之前检查它是否包含该项目。

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

在自定义类/对象上执行List.Contains()需要在自定义类上实现IEquatable<T>或覆盖Equals。同样在课堂上实现GetHashCode也是一个好主意。这是根据https://msdn.microsoft.com/en-us/library/ms224763.aspx

的文档
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;
    }
}

答案 3 :(得分:1)

可以将其编写为扩展方法以获得一些通用性,并且可以传递可选的自定义比较器...

/// <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();
}