Question

I am pretty new to Generic class in C#. I was trying to create one and ran into compiler error that I am not sure how to get around it.

Basically, I have a class G that implements ICollection

public class G<T> : ICollection<T> where T : IEqualityComparer
{
    private ArrayList _members = new ArrayList();

    public void Add(T item)
    {
        throw new NotImplementedException();
    }

    public void Clear()
    {
        throw new NotImplementedException();
    }

    public bool Contains(T item)
    {
        throw new NotImplementedException();
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        throw new NotImplementedException();
    }

    public int Count
    {
        get { throw new NotImplementedException(); }
    }

    public bool IsReadOnly
    {
        get { throw new NotImplementedException(); }
    }

    public bool Remove(T item)
    {
        throw new NotImplementedException();
    }

    public IEnumerator<T> GetEnumerator()
    {
        foreach (var item in _members)
        {
            yield return (T)item;
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

I wanted to be able to do comparison in G and Find item in G, so I have put a constraint that T has to be implementing IEqualityComparer. Then, I have an actual class called IntegerClass that implement IEqualityComparer as below. So far, so good, no compiler error.

public class IntegerClass : IEqualityComparer<int>
{
    public bool Equals(int x, int y)
    {
        throw new NotImplementedException();
    }

    public int GetHashCode(int obj)
    {
        throw new NotImplementedException();
    }
}

However, when I tried to create an instance of G above. I got a compiler error.

class Program
{
    static void Main(string[] args)
    {
        G<IntegerClass> i = new G<IntegerClass>();
    }
}

The error is:

The type 'TestGeneric.IntegerClass' cannot be used as type parameter 'T' in the generic type or method 'TestGeneric.G<T>'. 
There is no implicit reference conversion from 'TestGeneric.IntegerClass' to 'System.Collections.IEqualityComparer'

Could someone pinpoint what I have overlooked? Why would I need conversion? All I did was replacing class T with IntegerClass that implements IEqualityComparer interface. What should I do otherwise? I am new to this generic stuff, but have found it quite useful. I am thinking it could be very useful if I understand it correctly. Please help.

Update: Based on some suggestion, I saw what was wrong and I updated the code as follow:

   public class IntegerClass :  IEqualityComparer
    {
        public bool Equals(object x, object y)
        {
            throw new NotImplementedException();
        }
    public int GetHashCode(object obj)
    {
        throw new NotImplementedException();
    }
}
public class G<T> : ICollection<T> where T : IEqualityComparer
{
    private ArrayList _members = new ArrayList();

    public void Add(T item)
    {
        throw new NotImplementedException();
    }

    public void Clear()
    {
        throw new NotImplementedException();
    }

    public bool Contains(T item)
    {
        throw new NotImplementedException();
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        throw new NotImplementedException();
    }

    public int Count
    {
        get { throw new NotImplementedException(); }
    }

    public bool IsReadOnly
    {
        get { throw new NotImplementedException(); }
    }

    public bool Remove(T item)
    {
        throw new NotImplementedException();
    }

    public IEnumerator<T> GetEnumerator()
    {
        foreach (var item in _members)
        {
            yield return (T)item;
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

I think it might work but I got the warning below:

'TestGeneric.IntegerClass.Equals(object, object)' hides inherited member 'object.Equals(object, object)'. Use the new keyword if hiding was intended.

I know object has an Equals methods but the warning does not make sense. Should it say use the new keyword if hiding was NOT intended?

Était-ce utile?

La solution

Your constraint refers to the non-generic System.Collections.IEqualityComparer interface, which is not the same as IEqualityComparer<T>.
You could fix that error by specify the generic type in the constraint.


However, that's not what you want; an IEqualityComparer is a class that compares other things.

You want where T : IEquatable<T>.

Autres conseils

change your IntegerClass like below.

public class IntegerClass : IEqualityComparer<IntegerClass>
{
    public bool Equals(IntegerClass IC1, IntegerClass IC2)
    {
        throw new NotImplementedException();
    }

    public int GetHashCode(IntegerClass obj)
    {
        throw new NotImplementedException();
    }
}

Or you could resort it to the fact that Objects has an equality function. Hence, this would work

    public interface IMyComparer
    {
        object Comparer { get; }
    }

    public class IntegerClass : IMyComparer, IEqualityComparer<int>
    {

        public object Comparer { get { return this; } }

        public bool Equals(int x, int y)
        {
            throw new NotImplementedException();

        }

        public int GetHashCode(int obj)
        {
            throw new NotImplementedException();
        }
   }
   public class G<T> : ICollection<T> where T : IMyComparer
   {
     Your implementations
   }

Hope it helps.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top