简体   繁体   English

约束IEqualityComparer的通用类

[英]generic class with constraint IEqualityComparer

I am pretty new to Generic class in C#. 我对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 基本上,我有一个实现ICollection的类G

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. 我希望能够在G中进行比较,并能够在G中进行查找,因此我提出了一个约束,即T必须实现IEqualityComparer。 Then, I have an actual class called IntegerClass that implement IEqualityComparer as below. 然后,我有一个称为IntegerClass的实际类,它实现了IEqualityComparer,如下所示。 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. 但是,当我尝试在上面创建G的实例时。 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. 我所做的只是用实现IEqualityComparer接口的IntegerClass替换了类T。 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)'. 'TestGeneric.IntegerClass.Equals(object,object)'隐藏继承的成员'object.Equals(object,object)'。 Use the new keyword if hiding was intended. 如果要隐藏,请使用new关键字。

I know object has an Equals methods but the warning does not make sense. 我知道对象具有Equals方法,但是警告没有意义。 Should it say use the new keyword if hiding was NOT intended? 如果不想进行隐藏,是否应该说使用new关键字?

Your constraint refers to the non-generic System.Collections.IEqualityComparer interface, which is not the same as IEqualityComparer<T> . 您的约束指向非通用的System.Collections.IEqualityComparer接口,该接口与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. IEqualityComparer是比较其他内容的类。

You want where T : IEquatable<T> . 您要where T : IEquatable<T>

change your IntegerClass like below. 如下更改您的IntegerClass。

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. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM