c# generic method overload not consistent with abstract Visitor pattern

Overloading is done statically, so when you call VisitImpl(t), the compiler must pick the single best overloaded method that this call represents (if there is one). Since the type parameter T could be anything, the only method which is compatible is the generic method, and therefore all calls from Visit<T>(T t) call into VisitImpl<T>(T t).

EDIT

It looks like you may be coming from a C++ background, so perhaps it's worth noting that C++ templates are very different from C# generics; in particular, there's no such thing as specialization in C#, which may be why the behavior you see is unexpected. The C# compiler does not emit different code for the different types at which a generic method may be called (that is, the C# compiler calls the same generic method when you call Visit(1) and Visit("hello"), it does not generate specializations of the method at types int and string). At runtime, the CLR creates type specific methods, but this happens after compilation and cannot affect overload resolution.

EDIT - even more elaboration

C# does prefer non-generic methods to generic methods when the non-generic method is statically known to be applicable.

The C# compiler will pick a single method to call at any given call-site. Forget about overloading entirely, and give your methods each a different name; which of those renamed methods can be called at the call-site in question? Only the generic one. Therefore, even when the three names collide and overload resolution kicks in, that is the only overload which is applicable at that site, and is the method chosen.