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

解决方案 »

  1.   

    个人猜测因为aa这个属性返回的是一个值类型,你把它改成taa的指针应该就行了。
      

  2.   

    可以这样试试。paa = ^taa
    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;
      

  3.   

    http://delphi.about.com/od/adptips2006/qt/record_property.htm
    http://delphi.about.com/b/2006/11/29/delphi-question-proper-using-of-a-delphi-record-as-a-property-in-a-class.htm
    这两个地址讨论了些相关的东西,不过我也没看明白
      

  4.   


    但是,如果定义一个taa的变量,用变量给属性aa赋值,也是可以的,用指针是可以访问,但是我想知道为什么?
      

  5.   

    我试了试,的确不能编译,虽然不知道为什么不能编译,但我有以下几个解决办法:
    办法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;
      

  6.   

    解决这个问题没问题,只是我想知道为什么delphi要这么限制,似乎没有什么用,除了使编程更麻烦一点,亦或是编译器的一个bug?sonicer 给的链接全e文的,汗,先找个词典慢慢看~!~
      

  7.   

    从设计角度看,property是对field的一个封装,也就是说,不一定所有的值都可以写入,对象的设计者可能会对写入进行特别处理,导致某些值不能写入property。所以,为了保证封装的特性,不可能开放一个record的部分作为可写属性
    从语义的角度看,只有当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 的话,那么要改的代码就不是一点半点了,整个工程可能都要重新写,但这总比没源码的情况强。
    可能你认为这样是给编程更麻烦了,但实际上如果支持了,才是没事儿找事儿给工程性的程序设计带来极大的麻烦