我试图欺骗编译器从多个可用选项中选择特定的重载方法。
如果编译器选择带泛型参数的方法,它将始终通过引用传递,但出于内联原因,我更喜欢通过值传递参数。
但是我很难找到一个明确的规则来确定编译器如何选择要调用的重载方法。
请考虑以下代码:
program Project45;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
type
TX = type byte;
TTest<T> = class
class function Compare(const a,b: T): shortstring; overload; static; inline;
class function Compare(const a,b: integer): shortstring; overload; static; inline;
class function Compare(const a,b: cardinal): shortstring; overload; static; inline;
class function Compare(const a,b: shortint): shortstring; overload; static; inline;
class function Compare(const a,b: byte): shortstring; overload; static; inline;
class function Compare(const a,b: smallint): shortstring; overload; static; inline;
//class function Compare(const a,b: T): shortstring; overload; static; inline;
private
end;
class function TTest<T>.Compare(const a, b: integer): shortstring;
begin
Result:= 'Integer compare';
end;
class function TTest<T>.Compare(const a, b: byte): shortstring;
begin
Result:= 'Byte compare';
end;
class function TTest<T>.Compare(const a, b: smallint): shortstring;
begin
Result:= 'Smallint compare';
end;
class function TTest<T>.Compare(const a, b: int8): shortstring;
begin
Result:= 'Shortint Compare';
end;
class function TTest<T>.Compare(const a, b: cardinal): shortstring;
begin
Result:= 'Cardinal compare';
end;
class function TTest<T>.Compare(const A,B: T): shortstring;
begin
Result:= 'Generic compare';
end;
function test: boolean;
var
A,B: byte;
c,d: shortint;
w1,w2: word;
e,f: TX;
begin
a:= 1; b:= 255;
c:= 1; d:= -1;
e:= 1; f:= 255;
WriteLn('TTest<byte>.Compare(byte)'+#9+(TTest<byte>.Compare(a, b)));
WriteLn('TTest<shortint>.Compare(byte)'+#9+(TTest<shortint>.Compare(a, b)));
WriteLn('TTest<byte>.Compare(shortint)'+#9+(TTest<byte>.Compare(c, d)));
WriteLn('TTest<shortint>.Compare(shortint)'+#9+(TTest<shortint>.Compare(c, d)));
WriteLn('TTest<smallint>.Compare(word)'+#9+(TTest<smallint>.Compare(w1, w2)));
WriteLn('TTest<smallint>.Compare(smallint)'+#9+(TTest<smallint>.Compare(smallint(w1), smallint(w2))));
WriteLn('TTest<shortint>.Compare(tx)'+#9+#9+(TTest<shortint>.Compare(e, f)));
WriteLn('TTest<TX>.Compare(tx)'+#9+#9+(TTest<TX>.Compare(e, f)));
ReadLn;
end;
begin
Test;
end.
如果我将泛型方法放在类中,则输出以下内容:
TTest<byte>.Compare(byte) -> Generic compare
TTest<shortint>.Compare(byte) -> Byte compare
TTest<byte>.Compare(shortint) -> Shortint Compare
TTest<shortint>.Compare(shortint) -> Generic compare
TTest<smallint>.Compare(word) -> Integer compare
TTest<smallint>.Compare(smallint) -> Generic compare
TTest<shortint>.Compare(tx) -> Byte compare
TTest<TX>.Compare(tx) -> Generic compare
如果我将泛型方法放在最后,输出将更改为:
TTest<byte>.Compare(byte) -> Byte compare
TTest<shortint>.Compare(byte) -> Byte compare
TTest<byte>.Compare(shortint) -> Shortint Compare
TTest<shortint>.Compare(shortint) -> Shortint Compare
TTest<smallint>.Compare(word) -> Integer compare
TTest<smallint>.Compare(smallint) -> Smallint compare
TTest<shortint>.Compare(tx) -> Byte compare
TTest<TX>.Compare(tx) -> Generic compare
第一个有一个非常随机的感觉,第二个更有意义,但有时更改类型参数会使编译器更改其调用,有时更改参数本身会影响更改。
编译器使用什么规则来选择要调用的重载方法?