List<T>.Contains

J

JB

I've created a generic of type List<T> where T is a custom class. I
need to use the List<T>.Contains method. I know I need to implement
the IEqualityComparer but I can't seem to get the Contains method to
execute my Equals code. What am I doing wrong?

T is the following

NameValue : IEqualityComparer<NameValue>
{
public string Text;
public string Value;

public bool Equals(NameValue nv1, NameValue nv2)
{
if (nv1.Key == nv2.Key && nv1.Value == nv2.Value)
return true;
else
return false;
}

public int GetHashCode(NameValue nv)
{
return nv.Key.GetHashCode();
}
}

Thanks
JB
 
L

Lucian Wischik

JB said:
I've created a generic of type List<T> where T is a custom class. I
need to use the List<T>.Contains method. I know I need to implement
the IEqualityComparer but I can't seem to get the Contains method to
execute my Equals code. What am I doing wrong?

You don't need to implement IEqualityComparer. See the code below. NB.
The documentation says that List<T>.Contains uses
EqualityComparer.Default, so you providing your own IEqualityComparer
isn't going to do any good. But read the documentation for
EqualityComparer.Default. It says it will use System.IEquatable if T
supports it, but otherwise will fall back on the overrides of
Object.Equals and Object.GetHashCode. (and I've provided
implementations of these two).

class NameValue
{ public string Text, Value;
public override bool Equals(object obj)
{ NameValue that = obj as NameValue; if (that==null) return false;
return (this.Text==that.Text && this.Value==that.Value);
}
public override int GetHashCode()
{ return Text.GetHashCode() ^ Value.GetHashCode();
}
}

public static void Main(string[] args)
{ List<NameValue> mylist = new List<NameValue>();
NameValue x = new NameValue(); x.Text="hello"; x.Value="World";
mylist.Add(x);
NameValue y = new NameValue(); y.Text="hello"; y.Value="World";
bool c = mylist.Contains(y);
}


NB. For your NameValue, I'd be inclined to make it a struct. In which
case you should also provide == and !=, just for sake of good
programming practice. Here:


struct NameValue
{ public string Text, Value;

public override bool Equals(object obj)
{ if (obj==null || obj.GetType()!=this.GetType()) return false;
return this == ((NameValue)obj);
}

public override int GetHashCode()
{ return Text.GetHashCode() ^ Value.GetHashCode();
}

public static bool operator != (NameValue x, NameValue y)
{ return !(x==y);
}

public static bool operator == (NameValue x, NameValue y)
{ return (x.Text==y.Text && x.Value==y.Value);
}
}
 
O

Ole Nielsby

JB said:
I've created a generic of type List<T> where T is a custom
class. I need to use the List<T>.Contains method. I know
I need to implement the IEqualityComparer but I can't seem
to get the Contains method to execute my Equals code.
What am I doing wrong?

You are reading the docs too fast. The Remarks section of the
Contains method says:

This method determines equality using the default equality
comparer EqualityComparer.Default for T, the type of
values in the list.

So it doesn't help make the values implement IEqualityComparer.

If the List<T> class supported using a custom IEqualityComparer,
it would be specified as a constructor parameter.

Perhaps you could override the Equals method of your object,
though this isn't a particluarly elegant solution, introducing one
of these typecasts generics should help us eliminate, and also
possibly changing the behavior of NameValue objects in
other places (which might be good or bad...)

NameValue
{
public string Text;
public string Value;

public override bool Equals(object otherObject)
{
NameValue other = otherObject as NameValue;
if (other is NameValue && this.Key == other.Key && this.Value ==
other.Value)
return true;
else
return false;
}
}

I don't know what your code is doing but you should probably use
a collection that is designed to work with key-value pairs instead
of building your own key-value thing on top of a collection that
wasn't meant for this.

Hth/Ole N.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top