Due to an interesting code example, behind which Kim Madsen first suspected a possible bug in the Delphi compiler, I took a closer look at the calling behavior of overloaded methods that also contain generic type parameters. I was surprised by the possible bug since I use overloads with combinations of generic and non-generic methods in current projects without any obvious errors.
Here is a simplified version of Kim’s code:
TFoo = class(TObject) public function DoSomething(SomeObject: TValue): string; overload; function DoSomething<T>(SomeObject: T): string; overload; end; TBar = class(TObject) end; //... var Foo := TFoo.Create; var Bar := TBar.Create; Foo.DoSomething(Bar);
Which of the two possible variants of DoSomething should be called by Foo.DoSomething(Bar)?
At a first glance, I was inclined to say that the non-generic variant, i.e. function DoSomething(SomeObject: TValue): string; should be called, since after all no type parameter is specified and therefore the first variant matches best.
But in fact, the generic, second variant is called. I initially suspected “TValue” of “blocking” the overload resolution here, since TValue is actually an “artificial” RTTI.driven type.
Stefan Glienke came up with the correct hint:
Generic parameters are actually optional and the type is automatically inferred by the type of the variable that is passed. This “type inference” takes precedence over overload resolution and thus produces a better match than the “TValue” method.
Type-inference of generic methods is documented here btw.
So the following code actually calls a generic implementation, although no type parameter is specified in the call:
function DoSomething<T>(SomeObject: T): string; //... Foo.DoSomething(Bar); //<T> is inferred from "Bar"
Here is a Gist with full code to try: