反正有没有像行为一样使用该属性?

时间:2017-10-30 17:43:52

标签: delphi properties delphi-10-seattle

我有以下公式

X := X + F*(1-i div n);

哪里

X, F, i, n: integer;

我正在使用的代码就是这个

F := 7; // the initial speed with no friction.
n := 10; // the animation number of steps.
Hn := n * 2 ; 
X := 0;  // first Pos
i := 1;  
J := 1;
while J < Hn do
begin
  X := X + F * (1 - i div n);
  if X > Xmax then X := 0;  <-- line (1).
  if i >= n then Dec(i)
  else Inc(i);
  Inc(J); 
end;

如果有可能我想使用它但没有类/记录实现(不在类/记录实现/方法中)。不是确切的语法,只是相同的原则,而不是直接赋值给X,SetX是然后将结果分配给X.

X: integer write SetX; // This is not a correct delphi syntax. I added it to explain the behavior I want. 

function SetX(aValue: integer): integer;
const
  Xmax: SomeIntegerValue;
begin
  if aValue > Xmax then result := 0  
  else result := aValue; 
end;

所以我可以省略Line(1)。如果这是可能的,公式之后的所有行都将被省略,而while循环看起来像这样

while J < Hn do  // J will be incremented each time the loop wants to read it.    
begin
  X := X + F * (1 - i div n);
end;

有没有像行为一样使用该属性?

注意:我正在寻找一种方法来改变分配和读取变量的方式,就像在记录/类的属性中一样。

3 个答案:

答案 0 :(得分:2)

  

无论如何使用类似于类/记录之外的方法?

不,属性getter和setter只能在记录和类中实现。

答案 1 :(得分:0)

您可以使用

等本地功能
procedure YourProcedure;

var
  X: Integer;
  LJ: Integer;
function J: Integer;
begin
  Inc(LJ);
  Result := LJ;
end; 
procedure SetX(const AValue: Integer);
const
  Xmax: SomeIntegerValue;
begin
  if aValue > Xmax then X := 0  
  else X := aValue; 
end;
//...
begin
  while J < Hn do  // J will be incremented each time the loop wants to  read it.    
  begin
     SetX(X + F * (1 - i div n));
  end
end.

答案 2 :(得分:0)

我找到了一种方法来做我想做的事。我知道重载:=运算符是不可能的,但是强制编译器产生与重载运算符相同的行为。

重载不会让我控制LSA(左侧参数)。但它完全控制了隐式转换任何TType(在我的情况下,它是integer)到TXinteger。所以我所要做的就是确保每个运算符都会产生TType,这会强制编译器将其隐式转换为TXinteger

每次想要为TXinteger分配内容时,强制编译器使用我的隐式运算符意味着我控制赋值因此我重载了:=运算符。

以下是省略Line(1)的测试示例。

program Project4;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;



type
   TXinteger = record
     X: integer;
     class operator Add(a, b: TXinteger): integer;
     class operator Add(a: TXinteger; b:integer): integer;
     class operator Add(a: integer; b:TXinteger): integer;
     class operator Implicit(a: Integer): TXinteger;
     class operator Implicit(a: TXinteger): Integer;
   end;

// Example implementation of Add
class operator TXinteger.Add(a, b: TXinteger): integer;
begin
  result := a.X + b.X;
end;(**)

class operator TXinteger.Add(a: TXinteger; b:integer): integer;
begin
  result := a.X + b;
end;

class operator TXinteger.Add(a: integer; b:TXinteger): integer;
begin
  result := a + b.X;
end;

class operator TXinteger.Implicit(a: Integer): TXinteger;
const
  Xmax: integer = 10;
begin
  if a > Xmax then result.X := 0 else result.X := a;
end;

class operator TXinteger.Implicit(a: TXinteger): Integer;
begin
  result := a.X;
end;

var
X: TXinteger;
Hn, F, i,J, n: integer;
begin
  try
  F := 7;
  n := 10;
  Hn := n * 2 ;
  X := 0;
  i := 1;
  J := 1;
  while J < Hn do
    begin
    X := X + F * (1 - i div n);
    // Line (1)  is gone now.
    if i >= n then Dec(i)
    else Inc(i);
    Inc(J);
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

注意:对于这种情况,所有这一切都只是为了省略一行代码是没有意义的。我想分享这个,因为它让我们知道如何重载:=运算符。

我想要的是:

  • 更改X:Integer的读取方式(从变量x的存储中读取值)。
  • 更改X:Integer的分配方式。

通过重载所有使用X值的运算符,我完成了第一个。 通过强制编译器,如上所述,我完成了第二次。

谢谢大家的帮助。