Question

I have a relatively complicated data structure to model. I would like to do this with a record structure in Delphi, and the structure is complicated enough to justify splitting this into nested records. A simplified example:

    type
      TVertAngle = record
      strict private
        fDecDegrees: Double;
        fDegrees: integer;
        fMinutes: integer;
        fDeciSeconds: integer;
        function GetAngle: Double;
        function GetRadians: Double;
      public
        Valid: Boolean;
        procedure SetAsString(const Value: string; const AngleType: TInfoUnits);
        property DecDegrees: Double read GetAngle;
        property Radians: Double read GetRadians;
      end;

~~~~ other sub record declarations ~~~~~~

  TDataRecord = record
  strict private
    fHorzDistance: Double;
    fLeicaData: TRawMessageData;
    fUpdateTime: TDateTime;
    function DecodeGsi8(GsiWord: string): TGSiWord;
    function DecodeGsi16(GsiWord: string): TGSiWord;
  public
    GsiWord: TGSiWord;
    Valid: Boolean;
    InputMode: TDataModes;
    HorzAngle: THorzAngle;
    VertAngle: TVertAngle;
    HorzRange: TDistance;
    SlopeRange: TDistance;
    PrismOffset: TConstants;
~~~~ other sub record instances~~~~~~
    function SetMessage(RawMessage: string): Boolean;
~~~~ more stuff ~~~~~~

I currently have all this declared in the Interface section of the unit. I would prefer if only the main record structure was visible to anything using the unit, and at the moment all the sub records are also visible. If I move the record declarations into the Implementation section then I get compiler errors. How do I restructure so that I declare the sub-records prior to the main record but the sub-records are not published?

Was it helpful?

Solution

You can do one of the following:

1) Declare "sub records" in a separate "sub unit", so the "sub record" types are available only if the "sub unit" is declared in the "uses" clause. That is not exactly what you are looking for, since the "sub records" can be made visible for other units, but it provides some degree of hiding since the "sub unit" must be explicitely declared to reach "sub record" definitions.

2) Declare "sub records" as private nested types as follows:

type
  TMainRec = record
    private type
      TSubRec = record
        FSubField: Integer;
        procedure SubMethod;
      end;
    private
      FSubRec: TSubRec;
  end;

implementation

{ TMainRec.TSubRec }

procedure TMainRec.TSubRec.SubMethod;
begin
...
end;

OTHER TIPS

You can't do that, because even if the information doesn't need to be directly available to other code outside the unit, the compiler still needs to know about the sub-record types if you're going to use the main record somewhere.

One thing you could try is declaring the other types in another unit and then not using that other unit anywhere else. That doesn't really solve the problem, though; it just hides it a little.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top