views:

374

answers:

4
type
   TStaticArray = array[1..10] of integer;
   TDynamicArray = array of integer;

   TMyClass = class(TObject)
   private
      FStaticArray: TStaticArray;
      FDynamicArray: TDynamicArray;
   published
      property staticArray: TStaticArray read FStaticArray write FStaticArray; //compiler chokes on this
      property dynamicArray: TDynamicArray read FDynamicArray write FDynamicArray; //compiler accepts this one just fine
   end;

What's going on here? A static array gives the error, "published property 'staticArray' cannot be of type ARRAY" but dynamic arrays are just fine? I'm confused. Anyone know the reasoning behind this, and how I can work around it? (And no, I don't want to redeclare all my static arrays as dynamic. They're the size they are for a reason.)

A: 

Array properties cannot be published. So the following code does not work. The work around probably is to make it public.

   TMyClass = class(TObject)
   private
     FStaticArray: TStaticArray;

     function  GetFoo(Index: Integer): Integer;
     procedure SetFoo(Index: Integer; Value: Integer);
   public
     property Foo[Index: Integer] : Integer read GetFoo write SetFoo;
   end;
eed3si9n
Nope. That doesn't work either. Same error.
Mason Wheeler
How can you get the same error without using TStaticArray as property?
eed3si9n
Upvoted the downvote.
George Stocker
Because it's still an array property. And I downvoted that for a reason Gortok: it's a demonstrably incorrect answer. (Plug that in and it won't compile.)
Mason Wheeler
Mason's right. You cant publish array properties. That's just the way it works...
Vegar
Your example is wrong, because you still left the array property in the published section, rather than making it public (which would work). Please edit to correct, and I won't downvote. :-)
Ken White
A: 

The reason why you can publish a dynamic array property, is that dynamic arrays is implemented as references, or 'implicitly pointer'. They work more like strings, really.

The reason why you can't publish a static array, I don't know. It's just the way it's made, I guess..

For more details on how dynamic arrays work, take a look at DrBobs site

Vegar
+3  A: 

Published declaration tells the compiler to store information in the virtual method table. Only certain kinds of information can be stored.
The type of a published property cannot be a pointer, record, or array. If it is a set type, it must be small enough to be stored in an integer.
(O'REILLY, DELPHİ IN A NUTSHELL)

SimaWB
A: 

You have to have getters and setters. Under D2009 (didn't check other versions), the parameters to the getters/setters can't, for some reason, be const. ?

This works fine under D2009:

type
  TMyArray = array[0..20] of string;

type
  TMyClass=class(TObject)
  private
    FMyArray: TMyArray;
    function GetItem(Index: Integer): String;
    procedure SetItem(Index: Integer; Value: string);
  public
    property Items[Index: Integer]: string read GetItem write SetItem;
  end;

implementation

function TMyClass.GetItem(Index: Integer): string;
begin
  Result := '';
  if (Index > -1) and (Index < Length(FMyArray)) then
    Result := FMyArray[Index];
end;

procedure TMyClass.SetItem(Index: Integer; Value: string);
begin
  if (Index > -1) and (Index < Length(FMyArray)) then
    FMyArray[Index] := Value;
end;

NOTE: I would not typically just ignore Index values out of range, obviously. This was a quick example of how to make static array properties in a class definition; IOW, it's a compilable example only.

Ken White