C# HashSet2 to work exactly like the standard C# HashSet, not compiling

て烟熏妆下的殇ゞ 提交于 2019-12-08 00:37:38

问题


I'm creating my own HashSet that works as the standard HashSet, using a Dictionary. I'm doing this because C# for XNA XBox doesn't support HashSets.

This code is based on code from an example I found. I've edited the example to fix some of the problems but it still won't compile.

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'

I'd also be grateful for information on fixing it to be more like the standard HashSet if it deviates in it's behaviour or what it implments in ways that could be unexpected.

Continued from: stackoverflow.com/questions/9966336/c-sharp-xna-xbox-hashset-and-tuple

The most recent vertion of the class:

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

回答1:


You want to enumerate the keys, not the dictionary. Try this:

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

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



回答2:


The point is that the HashSet's GetEnumerator returns enumerator that enumerates keys of type T while dictionary's GetEnumerator returns enumerator that enumerates KeyValue object.

UPDATE

Change it to below:

public IEnumerator GetEnumerator()
{
    dict.Keys.GetEnumerator();
}

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



回答3:


You can simply use Mono's HashSet<T>. You might need to make some minor changes to #if, or remove some interfaces/attributes, but it works on .net.

It's using the MIT X11 license, which is permissive. https://github.com/mono/mono/blob/master/mcs/class/System.Core/System.Collections.Generic/HashSet.cs




回答4:


Just took a look at the source, and all implementations of GetEnumerator in the Dictionary<TKey, TValue> return the KeyCollection.Enumerator/ValueCollection.Enumerator objects instead of IEnumerator<T> (which is what we need). The good news is that the Key/ValueCollation.Enumerator implement both System.Collection.IEnumerator and IEnumerator<T> interfaces, so you can safely cast to those types.

Try doing this instead:

public IEnumerator GetEnumerator()
{
    return (IEnumerator)dict.Keys.GetEnumerator();
}

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


来源:https://stackoverflow.com/questions/10246572/c-sharp-hashset2-to-work-exactly-like-the-standard-c-sharp-hashset-not-compilin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!