Właściwość rekordowa

0

Witam wszystkich, potrzebuję pomocy przy projektowaniu klasy. Mam np. taki rekord:

TFooRec = record
  Counter: Integer;
  Index: Integer;
end;

Chcę go wykorzystać w klasie:

TFooClass = class
private
  FFooRec: TFooRec;
published
  property FooRec: TFooRec read FFooRec;
end;

Ale jest pewna przeszkoda, mianowicie w jaki sposób właściwość FooRec zadeklarować w klasie tak, bym mógł odczytywać Counter jedną procedurą, a Index inną?

Dla przykładu podam kod, który w żadnym wypadku się nie skompiluje, ale może naprowadzi was na sens pytania:

TFooClass = class
private
  FFooRec: TFooRec;

  function GetCounter: Integer;
  function GetIndex: Integer;
published
  FooRec: record
    property Counter: Integer read GetCounter;
    property Index: Integer read GetIndex;
  end;
end;

Ten kod się nie skompiluje, ale chodzi mi o to, żeby poszczególne pola rekordu odczytywać innymi funkcjami, ale żebym mógł się do tych właśnie pól rekordu odnosić się w kodzie w taki sposób:

procedure FooProc;
var
  FooClass: TFooClass;
  Counter: Integer;
begin
  { konstruktor }

  Counter := FooClass.FooRec.Counter;

  { destruktor }
end;

Może to i zakręcone ale potrzebuję zgrupować kilka właściwości w jedną, ale żeby można było odczytywać je innymi funkcjami.

Bardzo proszę o pomoc. Pozdrawiam.

PS: Będę jutro rano on-line to kuknę tutaj.

0

zmień record na class i będzie git (no i oczywiście odpowiednio oprogramuj)

0

Znaczy który rekord? Ten w private czy w published?

Ten w private nie musi być rekordem, te pola mogą być luźno:

TFooClass = class
private
  FCounter: Integer;
  FIndex: Integer;

  function GetCounter: Integer;
  function GetIndex: Integer;
published
  FooRec: record
    property Counter: Integer read GetCounter;
    property Index: Integer read GetIndex;
  end;
end;
0

Dzięki misiekd, nie wiem czy dobrze zrozumiałem, w każdym razie przestudiuje podany przez Ciebie kod i odpiszę. Jak będę miał jakieś problemy - dam znać.

Dziękuję z góry. Pozdrawiam.

0

W dalszym ciągu nie wiem, w jaki sposób mógłbym wykorzystać podany przez Ciebie kod... Jakoś nie mogę zrozumieć o co w nim chodzi...

Jak dla mnie kod na tamtej stronie nie dotyczy tematu, fakt faktem utworzone są właściwości opisane klasą, ale w dalszym ciągu sekcjia published wygląda tak:

 property Property1 : TExpandingRecord read FProperty1 write SetProperty1;
property Property2 : TExpandingRecord read FProperty2 write SetProperty2;
property Property3 : TExpandingRecord read FProperty3 write SetProperty3;

Czyli w dalszym ciągu widoczne w CodeCompletion będą trzy właściwości: Property1, property2 i Property3 z tylko taką różnicą, że każda z nich posiada jeszcze subitemy (IntegerProp, StringProp, CollectionProp) a nie o to mi chodziło...

Spróbuję jeszcze raz wyjaśnić:

mam dla przykładu taką klasę:

TFooClass = class
private
  FCount: Integer;
  FIndex: Integer;

  function GetCount: Integer;
  function GetIndex: Integer;
public
  constructor Create;
  destructor Destroy; override;
published
  property Count: Integer read GetCount;
  property Index: Integer read GetIndex;
end;

Chcę, aby w CodeCompletion właściwości Count i Index były umieszczone np. wewnątrz właściwości Data:

procedure Foo;
var
  FooObj: TFooClass;
  Count: Integer;
  Index: Integer;
begin
  { konstructor }

  Count := FooObj.Data.Count;
  Index := FooObj.Data.Index;

  { destruktor }
end;

Czyli właściwości Count i Index umieszczone są wewnątrz właściwości Data, lecz odczytywane są przez inne funkcje (GetCount i GetIndex).

Moje pytanie brzmi: w jaki sposób i gdzie mam zamieścić informacje o tym, że ww właściwości są wewnątrz Data?

0

Data musiało by być inna klasą. Tak jak w TStringList albo obiektach typu Memo czy RichEdit masz własnośc Strings (domyślna dla TStringList) albo Lines, która mają własności Count i inne albo metody. Wtedy dajesz property Data typu TMojTypData. O ile dobrze zrozumiałem co chcesz osiągnąć.

0

No tak, musiało by być inną klasą, ale jeżeli tak bym zrobił to w jaki sposób każdą właściwość tej innej klasy odczytywać inną funkcją?

Olesio, chcę pogrupować właściwości na kategorie tak, by na liście w CodeCompletion nie było wszystko pomieszane. Dam jeszcze inny przykład: mam w klasie przechowywać przykładowo informacje o pliku:

  • nazwa pliku (String)
  • ścieżka katalogu (String)
  • litera dysku (String)
  • ukryty (Boolean)
  • archiwalny (Boolean)
  • tylko do odczytu (Boolean)

Trzeba pogrupować te pola, które odnoszą się do nazwy pliku osobno, a te odnośnie atrybutów osobno. Dajmy na to, że pogrupowaliśmy je w ten sposób:

Grupa NazwaPliku:

  • nazwa pliku
  • ścieżka katalogu
  • litera dysku

Grupa Atrybuty:

  • ukryty
  • archiwalny
  • tylko do odczytu

No to mamy w pseudokodzie grupy. Teraz wykorzystując rekordy stworzylibyśmy te grupy tak:

TFileNameData = record
  FileName: String;
  Path: String;
  Drive: String;
end;

TAttributes = record
  Hidden: Boolean;
  Archival: Boolean;
  ReadOnly: Boolean;
end;

TFooClass = class
private
  FFileNameData: TFileNameData;
  FAttributes: TAttributes;
public
  constructor Create;
  destructor Destroy; override;
published
  property FileNameData: TFileNameData read FFileNameData;
  property Attributes: TAttributes read FAttributes;
end;

No i jak widać z tego kodu mamy dwie właściwości rekordowe, które można tylko odczytywać. Jeżeli chce pobrać nazwę pliku zawartą we właściwości rekordowej FileNameData, zrobiłbym to tak:

{...}
var
  FooClass: TFooClass;
  FileName: String;
begin
  {..}

  FileName := FooClass.FileNameData.FileName;

  {..}

Jak widać wpisujemy najpierw nazwę klasy, później grupę FileNameData i nazwę właściwości (tu FileName). Teraz potrzebuję odczytać każdą z pól rekordów inną funkcją, oto ich lista:

function GetFileName: String;
function GetPath: String;
function GetDrive: String;
function GetHidden: Boolean;
function GetArchival: Boolean;
function GetReadOnly: Boolean;

Ale jak mam to zaprogramować? Jak grupując te sześć właściwości do dwóch grup, odczytywać każdą z nich osobnymi funkcjami?

TFooClass = class
private
  FFileNameData: TFileNameData;
  FAttributes: TAttributes;

  function GetFileName: String;
  function GetPath: Stirng;
  function GetDrive: String;
  function GetHidden: Boolean;
  function GetArchival: Boolean;
  function GetReadOnly: Boolean;
{..}

Mam już je w sekcji private, ale jak zaprogramować właściwości by do każdej przypisać osobną funkcję zachowując grupy?

0

Nie wiem czy dobrze zrozumiałem w czym problem, ale wedlug mnie to umieszczasz te funkcje w klasach - kategoriach, które sobie utworzyłeś. Może jak Misiek będzie to Tobie dokładniej podpowie, bo ja przeglądając teraz na szybko może nie za bardzo dokładnie wczytałem się w to co już masz i co chcesz.

0
John Pablo napisał(a)

Czyli w dalszym ciągu widoczne w CodeCompletion będą trzy właściwości: Property1, property2 i Property3 z tylko taką różnicą, że każda z nich posiada jeszcze subitemy (IntegerProp, StringProp, CollectionProp)

zamiast trzy właściwości wstawisz tu RAZ Data a zamiast subitemy(IntegerProp, StringProp, CollectionProp) wstawisz subitemy (Count i Index) to dostaniesz dokładnie to:

Chcę, aby w CodeCompletion właściwości Count i Index były umieszczone np. wewnątrz właściwości Data:

Ja po przeczytaniu Twoich postów dalej nie mam pojęcia co chcesz zrobić jeśli powyższe Ci nie odpowiada

FileName := FooClass.FileNameData.FileName;
Jak widać wpisujemy najpierw nazwę klasy, później grupę FileNameData i nazwę właściwości (tu FileName)

przecież to jest dokładnie to samo co na tej stronie, którą Ci podałem
Jak widać wpisujemy najpierw nazwę klasy, później grupę Property1 i nazwę właściwości (tu IntegerProp)

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0