type
taa = record
aa: boolean;
bb: boolean;
end;
TForm2 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
faa: taa;
public
{ Public declarations }
property aa:taa read faa write faa;
end;var
Form2: TForm2;implementation{$R *.dfm}procedure TForm2.FormCreate(Sender: TObject);
begin
aa.aa := false;
aa.bb := false;
//faa.aa := false; //改成这个语句就可以编译通过
//faa.bb := false; //end;//用下面的代码也可以通过
//procedure TForm2.FormCreate(Sender: TObject);
//var
// dd: taa;
//begin
// dd.aa := false;
// dd.bb := false;
// aa := dd;
//end;
从来没注意过,还有这问题,谁能告诉我,为什么会有这样的限制?我用的是delphi6
taa = record
aa: boolean;
bb: boolean;
end;
TForm2 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
faa: taa;
function GetPaa: paa;
public
{ Public declarations }
property aa:paa read GetPaa;
end;
function TForm2.GetPaa: paa;
begin
Result := @faa;
end;
http://delphi.about.com/b/2006/11/29/delphi-question-proper-using-of-a-delphi-record-as-a-property-in-a-class.htm
这两个地址讨论了些相关的东西,不过我也没看明白
但是,如果定义一个taa的变量,用变量给属性aa赋值,也是可以的,用指针是可以访问,但是我想知道为什么?
办法1.首先从逻辑上来说,既然你将属性aa的读写都对应faa,那么直接将faa从私有成员转变为Public即可,从而省去了属性aa的定义,当然名称也应该从faa改为aa
办法2.使用一个临时的结构体来进行写:procedure TForm2.FormCreate(Sender: TObject);
var
tmpa:abcd;
begin
tmpa.a:=false;
tmpa.b:=false;
aa:=tmpa;
end;
从语义的角度看,只有当object/class.property作为“:=”的部分的时候,才调用write的处理过程,其它情况下一律调用read过程。换句话说,当你使用aa.bb的时候,编译器把它看成 function aa.Read: Boolean,而不是 procedure aa.Write(const Value: Boolean)。而read的返回值是个右值,对它写入值完全没意义,所以对它进行语法支持也是没意义的。最后说一点,property既直接读写成员变量,又支持通过函数/过程读写。虽然最后的编译结果除了rtti外,只不过是相当于宏替换,但在语法处理上是绝不能按照宏替换来的,必需按照最小支持的语法来设计。这个意思就是说,假如有 Foo: T read FFoo write FFoo,从语法上看,如果是宏替换,我们完全可以按照普通成员变量来处理,比如可以取地址,直接读写 Foo.xxx 等;但是如果有一天,需要把 Foo 改为 read GetFoo write WriteFoo 的话,那么要改的代码就不是一点半点了,整个工程可能都要重新写,但这总比没源码的情况强。
可能你认为这样是给编程更麻烦了,但实际上如果支持了,才是没事儿找事儿给工程性的程序设计带来极大的麻烦