Why does the Equals method return a different result from within the generic method? I think that there’s some automatic boxing here that I don’t understand.
Here’s an example that reproduces the behavior with .net 3.5 or 4.0:
static void Main(string[] args)
{
TimeZoneInfo tzOne = TimeZoneInfo.Local;
TimeZoneInfo tzTwo = TimeZoneInfo.FindSystemTimeZoneById(tzOne.StandardName);
Console.WriteLine(Compare(tzOne, tzTwo));
Console.WriteLine(tzOne.Equals(tzTwo));
}
private static Boolean Compare<T>(T x, T y)
{
if (x != null)
{
return x.Equals(y);
}
return y == null;
}
Output:
False
True
Edit: This code works as desired without many compromises:
private static Boolean Compare<T>(T x, T y)
{
if (x != null)
{
if (x is IEquatable<T>)
{
return (x as IEquatable<T>).Equals(y);
}
return x.Equals(y);
}
return y == null;
}
Followup: I filed a bug via MS Connect and it has been resolved as fixed, so it’s possible this will be fixed in the next version of the .net framework. I’ll update with more details if they become available.
PS: This appears to be fixed in .net 4.0 and later (by looking at the disassembly of TimeZoneInfo in mscorlib).
TimeZoneInfo does not override the Object Equals method, so it calls the default Object Equals, which apparently does not work as expected. I would consider this a bug in TimeZoneInfo. This should work:
The above will cause it to call
Equals<T>, which is the method you were calling above (it implicitly preferred the generic call because it was more specific to the parameter type than the Object Equals; inside the generic method, however, it had no way to be sure that such a generic Equals existed, since there was no constraint guaranteeing this).