Pan*_*mon 6 delphi overloading
在 Delphi 中,我可以这样做:
Type
TFourCC = Array[0..3] of AnsiChar;
Function Func(Param : TFourCC) : Boolean;
begin
{ ... }
end;
Func('ABCD'); // I can pass this as literal text without problems
Run Code Online (Sandbox Code Playgroud)
现在,我想将此参数设为可选。
Function Func(Param : TFourCC = 'ABCD') : Boolean;
begin
{ ... }
end;
Run Code Online (Sandbox Code Playgroud)
现在,编译器向我抛出一个错误: E2268 Parameters of this type cannot have default values
好的,所以我在想重载函数应该可以解决问题......
Function Func : Boolean; overload;
begin
{ ... }
end;
Function Func(Param : TFourCC) : Boolean; overload;
begin
{ ... }
end;
Func('ABCD'); // This line that worked in first example now gives an error
Run Code Online (Sandbox Code Playgroud)
不幸的是,Delphi 也不喜欢这样。在它首先接受参数作为TFourCC类型变量的地方,它现在给了我E2250 There is no overloaded version of 'Func' that can be called with these arguments.
我不同意这个错误告诉我的,当它没有超载时,同样的事情会起作用。
有人可以向我解释这背后的逻辑,以及可能的解决方案吗?我想保持TFourCC原样(不是字符串类型),这样可以更轻松地处理读取和写入。我宁愿避免在传递它之前先将它分配给一个变量,因为该函数将被大量使用..
不幸的是,这就是当前类型系统的工作方式。
但好消息是,您可以使用记录和运算符重载来变魔术。例如,与
type
TFourCC = record
strict private
function GetChar(Index: Integer): AnsiChar;
procedure SetChar(Index: Integer; const Value: AnsiChar);
public
class operator Implicit(AValue: AnsiString): TFourCC;
class operator Implicit(AValue: TFourCC): AnsiString;
class operator Equal(a, b: TFourCC): Boolean;
class operator NotEqual(a, b: TFourCC): Boolean;
property Chars[Index: Integer]: AnsiChar read GetChar write SetChar; default;
case Boolean of
False: (AnsiChars: array[0..3] of AnsiChar);
True: (Data: Cardinal)
end;
implementation
{ TFourCC }
class operator TFourCC.Implicit(AValue: AnsiString): TFourCC;
begin
if Length(AValue) <> 4 then
raise Exception.Create('Not a valid TFourCC string.');
Result.Data := PCardinal(@AValue[1])^;
end;
class operator TFourCC.Implicit(AValue: TFourCC): AnsiString;
begin
SetLength(Result, 4);
PCardinal(@Result[1])^ := AValue.Data;
end;
class operator TFourCC.Equal(a, b: TFourCC): Boolean;
begin
Result := a.Data = b.Data;
end;
class operator TFourCC.NotEqual(a, b: TFourCC): Boolean;
begin
Result := a.Data <> b.Data;
end;
function TFourCC.GetChar(Index: Integer): AnsiChar;
begin
Result := AnsiChars[Index];
end;
procedure TFourCC.SetChar(Index: Integer; const Value: AnsiChar);
begin
AnsiChars[Index] := Value;
end;
Run Code Online (Sandbox Code Playgroud)
您将获得所有这些好处:
procedure TForm1.FormCreate(Sender: TObject);
var
x: TFourCC;
begin
x := 'FINE'; // implicit conversion from string
ShowMessage(x); // implicit conversion to string
x[0] := 'D'; // can access parts for writing (without explicit member)
ShowMessage(x);
ShowMessage(x[0]); // can access parts for reading (without explicit member)
ShowMessage(x.Data.ToString); // can access underlying storage as a 32-bit integer
end;
Run Code Online (Sandbox Code Playgroud)
而且,你现在可以做
procedure TForm1.FormCreate(Sender: TObject);
var
x: TFourCC;
begin
x := 'FINE'; // implicit conversion from string
ShowMessage(x); // implicit conversion to string
x[0] := 'D'; // can access parts for writing (without explicit member)
ShowMessage(x);
ShowMessage(x[0]); // can access parts for reading (without explicit member)
ShowMessage(x.Data.ToString); // can access underlying storage as a 32-bit integer
end;
Run Code Online (Sandbox Code Playgroud)
不幸的是,我现在很着急,所以我现在不能仔细检查正确性或进一步评论!