Сегодня, разбираясь с проектом, который я пытаюсь перевести на Delphi 2009, натолкнулся на одну забавную недокументированную возможность. Наряду с помощниками классов (Class Helpers) введенными в последних версиях Delphi, разработчику доступны и помощники записей!
Стоит сразу отметить, что данная возможность не поддерживается редактором кода и Code Insight. Так в редакторе код подчеркивается красным, а в Code Insight добавленное недоступно.
НО, с точки зрения компилятора, следующий код абсолютно рабочий: Использовать новый метод можно, например, следующим образом: Не знаю, на сколько эта возможность может быть востребована, но она есть. P.S. К слову сказать, что Class Helpers разработчики не рекомендуют использовать постоянно, а про Record Helpers они и вообще умолчали. :)type
TRectHelper = record helper for TRect
function Width: integer;
end;
{ TRectHelper }
function TRectHelper.Width: integer;
begin
Result := Self.Right - Self.Left;
end;var
p: TRect;
begin
p.Top := 0;
p.Left := 0;
p.Bottom := 12;
p.Right := 12;
ShowMessage(inttostr(p.width));
end;
А чем они объясняют свою рекомендацию не использовать часто Class Helpers ?
ОтветитьУдалитьОни, не рекомендуют, поскольку эта возможность потенциально может быть источником трудноуловимых багов. И я так думаю, то что я описал в следующем посте про то как компилятор видит только один хелпер - далеко не единственный подводный камень.
ОтветитьУдалитьА вот так сработает
ОтветитьУдалитьprogram Project37;
uses
SysUtils,
Unit36 in 'Unit36.pas';
{$APPTYPE CONSOLE}
type
TSomeObjectHelper2 = class helper for TSomeObject
function z: integer;
end;
{ TSomeObjectHelper2 }
function TSomeObjectHelper2.z: integer;
begin
result := 2;
end;
var
obj:TSomeObject;
begin
obj := TSomeObject.Create;
try
writeln(obj.z);
writeln( UseY(obj));
readln;
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.
unit Unit36;
interface
type
TSomeObject = class
function X: integer;
end;
TSomeObjectHelper = class helper for TSomeObject
function y: integer;
end;
{ TSomeObjectHelper }
function UseY(const obj: TSomeObject):Integer;
implementation
function UseY(const obj: TSomeObject):Integer;
begin
Result := obj.y;
end;
function TSomeObjectHelper.y: integer;
begin
result := 1;
end;
{ TSomeObject }
function TSomeObject.X: integer;
begin
result := 0;
end;
Да и в справке написано буквально следующее
You can define and associate multiple class helpers with a single class type. However, only zero or one class helper applies in any specific location in source code. The class helper defined in the nearest scope will apply. Class helper scope is determined in the normal Delphi fashion (i.e. right to left in the unit's uses clause).