Почему некоторые массивы могут быть опубликованы, а другие нет? - PullRequest
5 голосов
/ 27 февраля 2009
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;

Что здесь происходит? Статический массив выдает ошибку: «опубликованное свойство staticArray не может иметь тип ARRAY», но с динамическими массивами все в порядке? Я не совсем понимаю. Кто-нибудь знает причину этого и как я могу обойти это? (И нет, я не хочу повторно объявлять все мои статические массивы как динамические. Они имеют размер, который они имеют по причине.)

Ответы [ 5 ]

6 голосов
/ 27 февраля 2009

Опубликованное объявление указывает компилятору хранить информацию в таблице виртуальных методов. Только определенные виды информации могут быть сохранены.
Тип опубликованного свойства не может быть указателем, записью или массивом. Если это тип набора, он должен быть достаточно маленьким, чтобы его можно было хранить в целом числе.
(О'Рейли, Дельфи в ореховой скорлупе)

1 голос
/ 18 апреля 2011
 TMyClass = class(TObject)
   private
     FStaticArray: TStaticArray;
     FIdx: Integer;
     function  GetFoo(Index: Integer): Integer;
     procedure SetFoo(Index: Integer; Value: Integer);
   public
     property Foo[Index: Integer] : Integer read GetFoo write SetFoo;
   published
     property Idx: Integer read fidx write fidx;
     property AFoo: Integer read GetAFoo writte SetAFoo;
   end;
implementation
function TMyClass.GetAFoo: Integer;
begin
  result := FStaticArray[FIdx];
end;
procedure TMyClass.SetAFoo(Value: Integer);
begin
  FStaticArray[FIdx] := Value;
end;
0 голосов
/ 01 марта 2009

Вы должны иметь геттеры и сеттеры. Под D2009 (не проверял другие версии) параметры для методов получения / установки не могут, по некоторым причинам, быть постоянными.

Это прекрасно работает под 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;

ПРИМЕЧАНИЕ. Я бы не стал просто игнорировать значения индекса вне диапазона, очевидно. Это был быстрый пример того, как сделать свойства статического массива в определении класса; IOW, это только компилируемый пример.

0 голосов
/ 27 февраля 2009

Причина, по которой вы можете опубликовать свойство динамического массива, заключается в том, что динамические массивы реализованы как ссылки или «неявный указатель». На самом деле они работают как струны.

Причину, по которой вы не можете опубликовать статический массив, я не знаю. Я думаю, это просто так ...

Подробнее о работе динамических массивов можно узнать на сайте DrBobs

0 голосов
/ 27 февраля 2009

Свойства массива не могут быть опубликованы. Так что следующий код не работает. Обходной путь, вероятно, должен сделать это 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;
...