Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.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# HashSet<;字节[]>;包含重复项_C# - Fatal编程技术网

C# HashSet<;字节[]>;包含重复项

C# HashSet<;字节[]>;包含重复项,c#,C#,我有一个IPV4列表,作为来自页面访问的字节[]。要获得唯一的列表,我想将它们添加到哈希集中。使用下面的代码将重复的条目放入HashSet,我过去认为这是不可能的 byte[] a = new byte[] {0,0,0,1}; byte[] b = new byte[] {0,0,0,1}; HashSet<byte[]> hashBytes = new HashSet<byte[]>(); hashBytes.Add(a); hashBytes.Add(b); b

我有一个IPV4列表,作为来自页面访问的字节[]。要获得唯一的列表,我想将它们添加到哈希集中。使用下面的代码将重复的条目放入HashSet,我过去认为这是不可能的

byte[] a = new byte[] {0,0,0,1};
byte[] b = new byte[] {0,0,0,1};

HashSet<byte[]> hashBytes = new HashSet<byte[]>();
hashBytes.Add(a);
hashBytes.Add(b);
byte[]a=新字节[]{0,0,0,1};
字节[]b=新字节[]{0,0,0,1};
HashSet hashBytes=新HashSet();
添加(a);
hashBytes.Add(b);
我希望hashset只包含a,但它同时包含a和b

编辑:根据我在附加代码中添加的注释:


    public class IPComparer : IEqualityComparer<byte[]>
    {
        public bool Equals(byte[] a, byte[] b)
        {
            //They are not an IP address
            if (a.Length != 4 && b.Length != 4)
            {
                return false;
            }
            for (int i = 0; i < a.Length; i++)
            {
                if (a[i] != b[i])
                {
                    return false;
                }
            }
            return true;
        }
        public int GetHashCode(byte[] a)
        {
            uint b = 0;
            for (int i = 0; i < a.Length; i++)
            {
                b = ((b << 23) | (b >> 9)) ^ a[i];
            }
            return unchecked((int)b);
        }

公共类IPComparer:IEqualityComparer
{
公共布尔等于(字节[]a,字节[]b)
{
//它们不是IP地址
如果(a.长度!=4和&b.长度!=4)
{
返回false;
}
for(int i=0;i9))^a[i];
}
未选中返回((int)b);
}

我还使用新的HashSet(IPComparer)而不是常规的比较器创建了HashSet。结果没有改变。

要在hash集中使用,您的类必须正确实现
GetHashCode
Equals
。对于
byte[]
-数组通常不会覆盖这些方法,因此哈希集是基于引用相等而不是值相等进行比较的


最简单的解决方案是使用
IPAddress
而不是
byte[]
。如果这不是一个选项,您必须编写自己的比较器并将其传递给哈希集。您可以使用
SequenceEquals
按值比较数组;好的哈希值有点棘手,因为如果不缓存值,这将非常慢-您可能需要创建自己的类来保存
字节[]
并正确地实现
Equals
GetHashCode
(哪种类型会让您回到
IPAddress
:)).

有一个内置的ip地址类型@EdPlunkettjust仅供参考,您似乎正在使用equals方法验证某个内容是否为ip地址,如果不是,则返回false。这是不正确的,首先传入的一个字节数组将是哈希集中已经存在的字节数组,其次,这不是此接口或满足的条件hod是关于,它只是问它们是否相等,第三个事实是返回false,这意味着它不相等,因此最终可能会被添加到哈希集中,所以我花了一点时间才明白你想说什么。Equals函数中的第一个if语句应该返回true而不是false,以避免被添加到哈希集中。更改了它不管怎样,都不能使函数按预期工作。我创建了在编辑中看到的附加代码,并编写了一个带有一些假设的Equals函数。尽管在初始化时调用了自定义Equals函数,但添加到集合中似乎并没有调用自定义Equals函数。我尝试使用IPAddress,但效果很好,但速度很慢。因此,我发现转换为n int32(4x8位)工作正常,每行只需要额外5个刻度,这在业务层面上解决了问题,但在计算机科学层面上却没有。幸运的是,每十亿行只需要额外500亿个刻度(0.8分钟),这一点在我看来可以忽略不计。@int
Equals
仅用于解决散列之间的冲突-如果您有两个具有相同散列的对象,则使用
Equals
对它们进行比较;否则您知道它们是不同的对象。如果您不需要支持IPv6,int可以正常工作。此注释使我了解了实际情况计算机科学解决方案,考虑到编写剩余的代码以正确比较字节数组是很简单的。感谢您的见解。