Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Not Compare Generic Values

Tags:

c#

.net

generics

I am creating a generic class to hold widgets and I am having trouble implementing the contains method:

public class WidgetBox<A,B,C>
{
    public bool ContainsB(B b)
    {
        // Iterating thru a collection of B's
        if( b == iteratorB )  // Compiler error.
        ...
    }
}

Error: Operator '==' cannot be applied to operands of type 'V' and 'V'

If I can not compare types, how am I to implement contains? How do dictionaries, lists, and all of the other generic containers do it??

like image 922
Steve H. Avatar asked Feb 10 '10 16:02

Steve H.


2 Answers

You have a few options here

The first is to use Object.Equals:

if(b.Equals(iteratorB)) {
    // do stuff
}

Be careful using this option; if B does not override Object.Equals then the default comparsion is reference equality when B is a reference type and value equality when B is a value type. This might not be the behavior that you are seeking and is why without additional information I would consider one of the next two options.

The second is to add a constraint that B is IComparable:

public class WidgetBox<A, B, C> where B : IComparable 

so that

if(b.CompareTo(iteratorB) == 0) {
    // do stuff
}

A third is to require an IEqualityComparer<B> be passed to the constructor of WidgetBox

public class WidgetBox<A, B, C> {
    IEqualityComparer<B> _comparer;
    public WidgetBox(IEqualityComparer<B> comparer) {
        _comparer = comparer;
    }
    // details elided
}

Then:

if(_comparer.Equals(b, iteratorB)) {
    // do stuff
}

With this last option you can provide an overload that defaults to EqualityComparer<T>.Default:

public WidgetBox() : this(EqualityComparer<T>.Default) { }
like image 86
jason Avatar answered Oct 08 '22 01:10

jason


Not all objects implement == but all will have Equals (although it may be inherited from Object.Equals).

public class WidgetBox<A,B,C>
{
    public bool ContainsB(B b)
    {
        // Iterating thru a collection of B's
        if( b.Equals(iteratorB) )
        ...
    }
}
like image 38
Yuriy Faktorovich Avatar answered Oct 08 '22 01:10

Yuriy Faktorovich