只读记录中的Delphi 2010+和“左侧无法分配”:这可以禁用吗?

时间:2011-07-01 14:53:51

标签: delphi delphi-2010

我知道what changed。我知道为什么。但..

TComplicatedCallMaker = record
    Param1: TRecordType;
    Param2: TRecordType;
    {...}
    Param15: TRecordType;
    procedure Call;
end;

function ComplicatedCall: TComplicatedCallMaker;
begin
 { Fill default param values }
end;

procedure DoingSomeWorkHere;
begin
  with ComplicatedCall do begin
    Param7 := Value7;
    Param12 := Value12;
    Call;
  end;
end;

这在Delphi 2010之前已经完全有效。这是一种非常有用的技术,用于进行接受大量参数但通常只需要两个或三个的调用。但是从来没有相同的。

现在它给了......猜怎么着?

E2064: Left side cannot be assigned to.

这种有用的新行为不能以某种方式被禁用吗?关于如何修改模式以使其有效的任何想法?

因为没有明显的理由,认真地失去了这种方便的技术(并重写了一堆代码)......

2 个答案:

答案 0 :(得分:3)

我觉得这有点令人惊讶,但是既然你说它确实你确实是对的。我猜这个改变是在没有考虑记录方法的情况下做出的。如果没有调用方法的能力,那么这个结构将毫无意义。

无论如何,编译器不会让你摆脱困境,所以你必须这样做:

type
  TRecordType = record end;
  TComplicatedCallMaker = record
    Param1: TRecordType;
    procedure Call;
  end;

function ComplicatedCall: TComplicatedCallMaker;
begin
 { Fill default param values }
end;

procedure DoingSomeWorkHere(const Value: TRecordType);
var
  CallMaker: TComplicatedCallMaker;
begin
  CallMaker := ComplicatedCall;
  with CallMaker do begin
    Param1 := Value;
    Call;
  end;
end;

答案 1 :(得分:1)

我......我想我做到了

我希望Delphi开发人员看到他们让程序员做的事情!

type
  PCallMaker = ^TCallMaker;
  TCallMaker = record
    Param1: integer;
    Param2: integer;
    function This: PCallMaker; inline;
    procedure Call; inline;
  end;

function TCallMaker.This: PCallMaker;
begin
  Result := @Self;
 { Record functions HAVE to have correct self-pointer,
  or they wouldn’t be able to modify data. }
end;

procedure TCallMaker.Call;
begin
  writeln(Param1, ' ', Param2);
end;

function CallMaker: TCallMaker; inline
begin
  Result.Param1 := 0;
  Result.Param2 := 0;
end;

procedure DoingSomeWorkHere;
var cm: TCallMaker;
begin
 {Test the assumption that cm is consistent}
  cm := CallMaker;
  if cm.This <> @cm then
    raise Exception.Create('This wasn''t our lucky day.');

 {Make a call}
  with CallMaker.This^ do begin
    Param1 := 100;
    Param2 := 500;
    Call;
  end;
end;

这样可以保留旧版本的所有优点(速度,简单性,小调用开销)但是这种方法没有任何隐藏的问题吗?