T
taumuon
I've got an object, Person, that supports IEquatable<Person>. It
implements
bool Equals(Person obj)
as well as overriding
bool Equals(object obj)
I've got a container type that holds a member object of generic type
T, that supports IEquatable<T>, and a method, DoComparisons(T obj) to
compare the member object to the object passed in.
In the method, if I call:
member.Equals(obj);
Then the Equals(Person obj) overload is called,
but if I cast the member to IEquatable<Person> and then call
((IEquatable<Person>)member).Equals(obj);
Then the Equals(object obj) overload is called.
My question is why? The type T should have been resolved to Person
when I created my container, why does the first call result in the
correct method being called on the interface, whereas when the object
is cast to IEquatable<Person> it does not? Surely both should be doing
the same thing?
Here's the full code:
using System;
using System.Collections.Generic;
using System.Text;
namespace EquatableTest
{
public class Program
{
static void Main(string[] args)
{
Container<Person> container = new Container<Person>(new
Person("Gary Evans"));
Person person = new Person("Gary Evans");
container.DoComparisons(person);
}
}
public class Person : IEquatable<Person>
{
private string firstName;
private string lastName;
public Person(string fullName)
{
string[] names = fullName.Split(' ');
this.firstName = names[0];
this.lastName = names[names.Length - 1];
}
#region IEquatable<Person> Members
public bool Equals(Person other)
{
Console.Write("Equals(Person other) called.");
return ToString() == other.ToString();
}
#endregion
public override string ToString()
{
return string.Concat(firstName, " ", lastName);
}
public override int GetHashCode()
{
return ToString().GetHashCode();
}
public override bool Equals(object obj)
{
Console.Write("Equals(object other) called.");
Person person = obj as Person;
return ((person != null) && (ToString() ==
person.ToString()));
}
}
public class Container<T> where T : IEquatable<T>
{
private T member;
public Container(T t)
{
member = t;
}
public void DoComparisons(T obj)
{
Console.Write("Calling member.Equals() cast as
IEquatable<T>. ");
bool result = member.Equals(obj);
Console.WriteLine(" Result:" + result.ToString());
Console.Write("Calling member.Equals() cast as
IEquatable<Person>. ");
result = ((IEquatable<Person>)member).Equals(obj);
Console.WriteLine(" Result:" + result.ToString());
}
}
}
Cheers!
Gary
implements
bool Equals(Person obj)
as well as overriding
bool Equals(object obj)
I've got a container type that holds a member object of generic type
T, that supports IEquatable<T>, and a method, DoComparisons(T obj) to
compare the member object to the object passed in.
In the method, if I call:
member.Equals(obj);
Then the Equals(Person obj) overload is called,
but if I cast the member to IEquatable<Person> and then call
((IEquatable<Person>)member).Equals(obj);
Then the Equals(object obj) overload is called.
My question is why? The type T should have been resolved to Person
when I created my container, why does the first call result in the
correct method being called on the interface, whereas when the object
is cast to IEquatable<Person> it does not? Surely both should be doing
the same thing?
Here's the full code:
using System;
using System.Collections.Generic;
using System.Text;
namespace EquatableTest
{
public class Program
{
static void Main(string[] args)
{
Container<Person> container = new Container<Person>(new
Person("Gary Evans"));
Person person = new Person("Gary Evans");
container.DoComparisons(person);
}
}
public class Person : IEquatable<Person>
{
private string firstName;
private string lastName;
public Person(string fullName)
{
string[] names = fullName.Split(' ');
this.firstName = names[0];
this.lastName = names[names.Length - 1];
}
#region IEquatable<Person> Members
public bool Equals(Person other)
{
Console.Write("Equals(Person other) called.");
return ToString() == other.ToString();
}
#endregion
public override string ToString()
{
return string.Concat(firstName, " ", lastName);
}
public override int GetHashCode()
{
return ToString().GetHashCode();
}
public override bool Equals(object obj)
{
Console.Write("Equals(object other) called.");
Person person = obj as Person;
return ((person != null) && (ToString() ==
person.ToString()));
}
}
public class Container<T> where T : IEquatable<T>
{
private T member;
public Container(T t)
{
member = t;
}
public void DoComparisons(T obj)
{
Console.Write("Calling member.Equals() cast as
IEquatable<T>. ");
bool result = member.Equals(obj);
Console.WriteLine(" Result:" + result.ToString());
Console.Write("Calling member.Equals() cast as
IEquatable<Person>. ");
result = ((IEquatable<Person>)member).Equals(obj);
Console.WriteLine(" Result:" + result.ToString());
}
}
}
Cheers!
Gary