Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 仅将唯一项添加到列表中_C#_.net_C# 4.0 - Fatal编程技术网

C# 仅将唯一项添加到列表中

C# 仅将唯一项添加到列表中,c#,.net,c#-4.0,C#,.net,C# 4.0,我正在将远程设备添加到一个列表中,因为它们会通过网络宣布自己。我只想在之前没有添加设备的情况下将其添加到列表中 通知遇到了一个异步套接字侦听器,因此添加设备的代码可以在多个线程上运行。我不确定我做错了什么,但无论我做了什么尝试,最终都会出现重复。这是我目前拥有的 lock (_remoteDevicesLock) { RemoteDevice rDevice = (from d in _remoteDevices where d.U

我正在将远程设备添加到一个列表中,因为它们会通过网络宣布自己。我只想在之前没有添加设备的情况下将其添加到列表中

通知遇到了一个异步套接字侦听器,因此添加设备的代码可以在多个线程上运行。我不确定我做错了什么,但无论我做了什么尝试,最终都会出现重复。这是我目前拥有的

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

如果您的需求没有重复项,那么应该使用

当项目已经存在时,将返回false(如果这对您很重要)


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

就像公认的答案说哈希集没有顺序一样。如果订单很重要,您可以继续使用列表,并在添加项目之前检查列表是否包含该项目

if (_remoteDevices.Contains(rDevice))
    _remoteDevices.Add(rDevice);
在自定义类/对象上执行List.Contains()需要在自定义类上实现
IEquatable
,或者重写
Equals
。在类中也实现
GetHashCode
也是一个好主意。这是根据

公共类远程设备:IEquatable
{
私有只读int-id;
公共远程设备(int uuid)
{
id=id
}
公共整数GetId
{
获取{return id;}
}
// ...
公共布尔等于(远程设备其他)
{
if(this.GetId==other.GetId)
返回true;
其他的
返回false;
}
公共覆盖int GetHashCode()
{
返回id;
}
}
//HashSet只允许列表中的唯一值
HashSet uniqueList=新HashSet();
变量a=唯一列表。添加(1);
var b=唯一列表。添加(2);
var c=唯一列表。添加(3);
var d=唯一列表。添加(2);//不应添加到列表中,但不会使应用程序崩溃
//字典只允许列表的唯一键,值可以重复
Dictionary dict=新字典();
添加(1,“快乐”);
添加(2,“微笑”);
添加(3,“快乐”);
dict.Add(2,“Sad”);//应失败//运行时错误“已添加具有相同密钥的项”。应用程序将崩溃
//字典只允许列表的唯一键,值可以重复
Dictionary dictRev=新字典();
添加(“快乐”,1);
添加(“微笑”,2);
添加(“快乐”,3);//应失败//运行时错误“已添加具有相同密钥的项”。应用程序将崩溃
添加(“Sad”,2);

RemoteDevice的定义是什么??出于调试目的,您是否可以使用时间戳字段扩展您的_remoteDevices类?\u remoteDevices.lastSeen=now?即将添加此答案。您可以使用这个重载来定义比较-这里的一个重要注意事项是,HashSet不保证遵守插入顺序。因此,如果顺序很重要(项目需要以与您放入列表相同的顺序出现在列表中,如
列表
),那么HashSet就不能正常工作。非常感谢。为了线程安全,我还需要保留锁吗?或者有更好的方法吗?@Oli您需要保留锁,但是操作会更快,这样他们就不会彼此等待太久。不幸的是,没有
ConcurrentSet
类。但是,有一个
ConcurrentDictionary
类,因此您可以使用它,将值存储为键,只需在值中存储
null
。@Oli:如果我是您,我会发布另一个问题来解决这个问题(GetHashCode&Equals的完整源代码,以及它们在您不希望它们匹配时匹配的情况).hi thx,但是如果因为我使用了对其他人代码的引用而无法重写,该怎么办?在这里,一个人该怎么做?
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;
    }
}
//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);