Unless you use the dynamic keyword, binding decisions in C# are made at compile-time rather than runtime.
The situation with a type constraint is no different to what happens in the following two methods:
void Foo1 (object x) { x.Equals (x); }
void Foo2<T> (IEquatable<T> x) { x.Equals(x); }
The call to Equals in Foo1 binds to object's Equals method, whereas the Equals in Foo2 binds to IEquatable<T>'s Equals method. The latter avoids boxing overhead and so is faster.
Bear in mind, though, that avoiding boxing is a micro-optimization. It's worth doing if either:
(1) It can be done effortlessly (IEquatable<T> might be included in this category)
(2) You're trying to make code that's called millions of times in a loop run faster
Joe
This post has been edited by JoeAlbahari: 15 February 2012 - 06:35 PM