C# HashSet2 的工作方式与标准 C# HashSet 完全相同,无需编译

本文关键字:编译 HashSet HashSet2 工作 方式 标准 | 更新日期: 2023-09-27 18:31:42

我正在使用字典创建自己的HashSet,它作为标准HashSet工作。我这样做是因为 C# for XNA XBox 不支持 HashSets。

此代码基于我找到的示例中的代码。我已经编辑了该示例以解决一些问题,但它仍然无法编译。

public class HashSet2<T> : ICollection<T>
{
    private Dictionary<T, Int16> dict;
    // code has been edited out of this example
    // see further on in the question for the full class
    public IEnumerator<T> GetEnumerator()
    {
        throw new NotImplementedException();
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return dict.GetEnumerator();
    }
}

.

'HashSet2<T>' does not implement interface member
'System.Collections.IEnumerable.GetEnumerator()'.
'HashSet2<T>.GetEnumerator()' cannot implement
'System.Collections.IEnumerable.GetEnumerator()'
because it does not have the matching return type of
'System.Collections.IEnumerator'
如果它的行为偏离或以

意想不到的方式施加什么,我也非常感谢有关修复它以更像标准 HashSet 的信息。

续自: stackoverflow.com/questions/9966336/c-sharp-xna-xbox-hashset-and-tuple

该类的最新版本:

public class HashSet2<T> : ICollection<T>
{
    private Dictionary<T, Int16> dict;
    // Dictionary<T, bool>
    public HashSet2()
    {
        dict = new Dictionary<T, short>();
    }
    public HashSet2(HashSet2<T> from)
    {
        dict = new Dictionary<T, short>();
        foreach (T n in from)
            dict.Add(n, 0);
    }
    public void Add(T item)
    {
        // The key of the dictionary is used but not the value.
        dict.Add(item, 0);
    }
    public void Clear()
    {
        dict.Clear();
    }
    public bool Contains(T item)
    {
        return dict.ContainsKey(item);
    }
    public void CopyTo(
        T[] array,
        int arrayIndex)
    {
        throw new NotImplementedException();
    }
    public bool Remove(T item)
    {
        return dict.Remove(item);
    }
    public System.Collections.IEnumerator GetEnumerator()
    {
        return ((System.Collections.IEnumerable)
            dict.Keys).GetEnumerator();
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return ((IEnumerable<T>)
            dict.Keys).GetEnumerator();
    }
    public int Count
    {
        get {return dict.Keys.Count;}
    }
    public bool IsReadOnly
    {
        get {return false;}
    }
}

C# HashSet2 的工作方式与标准 C# HashSet 完全相同,无需编译

你想要枚举键,而不是字典。试试这个:

public IEnumerator GetEnumerator()
{
    return ((IEnumerable)dict.Keys).GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
    return ((IEnumerable<T>)dict.Keys).GetEnumerator();
}

关键是 HashSet 的 GetEnumerator 返回枚举类型为 T 键的枚举器,而字典的 GetEnumerator 返回枚举 KeyValue 对象的枚举器。

更新

将其更改为以下内容:

public IEnumerator GetEnumerator()
{
    dict.Keys.GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
    return dict.Keys.GetEnumerator();
}
你可以

简单地使用Mono的HashSet<T>。您可能需要对#if进行一些小的更改,或删除一些接口/属性,但它适用于 .net。

它使用的是 MIT X11 许可证,这是宽松的。 https://github.com/mono/mono/blob/master/mcs/class/System.Core/System.Collections.Generic/HashSet.cs

只是看了一下源代码,Dictionary<TKey, TValue>中 GetEnumerator 的所有实现都返回 KeyCollection.Enumerator/ValueCollection.Enumerator 对象而不是 IEnumerator<T>(这是我们所需要的)。好消息是,Key/ValueCollation.Enumerator同时实现System.Collection.IEnumeratorIEnumerator<T>接口,因此您可以安全地转换为这些类型。

请尝试改为执行以下操作:

public IEnumerator GetEnumerator()
{
    return (IEnumerator)dict.Keys.GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
    return (IEnumerator<T>)dict.Keys.GetEnumerator();
}