Computerwissenschaften

Delphi Record Helpers für Sets und andere einfache Typen

Delphi Record Helpers für Sets und andere einfache Typen

Grundlegendes zu Delphi-Klassen- (und Datensatz-) Helfern führt eine Funktion der Delphi-Sprache ein, mit der Sie die Definition einer Klasse oder eines Datensatztyps erweitern können, indem Sie vorhandenen Klassen und Datensätzen Funktionen und Prozeduren (Methoden) ohne Vererbung hinzufügen .

In der XE3 Delphi-Version wurden Datensatz-Helfer leistungsfähiger, indem einfache Delphi-Typen wie Zeichenfolgen, Ganzzahlen, Aufzählungen, Mengen und ähnliches erweitert werden konnten.

Die System.SysUtils-Einheit von Delphi XE3 implementiert einen Datensatz mit dem Namen „TStringHelper“, der eigentlich ein Datensatz-Helfer für Zeichenfolgen ist.

Mit Delphi XE3 können Sie den nächsten Code kompilieren und verwenden:

var
s : string;
begin
s := 'Delphi XE3';
s.Replace('XE3', 'rules', []).ToUpper;
end;

 

Damit dies möglich ist, wurde in Delphi ein neues Konstrukt „record helper for [simple type]“ erstellt. Für Zeichenfolgen ist dies „Typ TStringHelper=Aufzeichnungshelfer für Zeichenfolge“. Der Name lautet „Record Helper“, aber es geht nicht um das Erweitern von Datensätzen, sondern um das Erweitern einfacher Typen wie Zeichenfolgen, Ganzzahlen und dergleichen.

In System und System.SysUtils gibt es andere vordefinierte Datensatzhilfen für einfache Typen, darunter: TSingleHelper, TDoubleHelper, TExtendedHelper, TGuidHelper (und einige andere). Sie können dem Namen entnehmen, welchen einfachen Typ der Helfer erweitert.

Es gibt auch einige praktische Open Source-Helfer wie TDateTimeHelper .

 

Aufzählungen? Helfer für Aufzählungen?

Aufzählungen setzt

Aufzählungen und Sätze, die als einfache Typen behandelt werden, können jetzt (in XE3 und darüber hinaus) auch um Funktionen erweitert werden, die ein Datensatztyp haben kann: Funktionen, Prozeduren und dergleichen.

Hier ist eine einfache Aufzählung („TDay“) und ein Aufzeichnungshelfer:

type
TDay=(Monday=0, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
TDayHelper=record helper for TDay
function AsByte : byte;
function ToString : string;
end;

function TDayHelper.AsByte: byte;
begin
result := Byte(self);
end;
function TDayHelper.ToString: string;
begin
case self of
Monday: result := 'Monday';
Tuesday: result := 'Tuesday';
Wednesday: result := 'Wednesday';
Thursday: result := 'Thursday';
Friday: result := 'Friday';
Saturday: result := 'Saturday';
Sunday: result := 'Sunday';
end;
end;

var
aDay : TDay;
s : string;
begin
aDay := TDay.Monday;
s := aDay.ToString.ToLower;
end;

Konvertieren Sie eine Delphi-Aufzählung in eine Zeichenfolgendarstellung

Sets? Helfer für Sets?

TDays=set of TDay;

var
days : TDays;
s : string;
begin
days := [Monday .. Wednesday];
days := days + [Sunday];
end;

 

ABER, wie großartig wäre es, in der Lage zu sein:

var
days : TDays;
b : boolean;
begin
days := [Monday, Tuesday]
b := days.Intersect([Monday, Thursday]).IsEmpty;

type
TDaysHelper=record helper for TDays
function Intersect(const days : TDays) : TDays;
function IsEmpty : boolean;
end;
...
function TDaysHelper.Intersect(const days: TDays): TDays;
begin
result := self * days;
end;
function TDaysHelper.IsEmpty: boolean;
begin
result := self=[];
end;

 

Für jeden Satztyp, der um eine Aufzählung herum aufgebaut ist, benötigen Sie einen separaten Helfer, da Aufzählungen und Sätze leider nicht zu Generika und generischen Typen gehören .

Dies bedeutet, dass Folgendes nicht kompiliert werden kann:

//NO COMPILE OF ALIKE!
TGenericSet=set of ;

TEnum Simple Generics Enum Beispiel

Rekordhelfer für Byte-Set!

type
TByteSet=set of Byte;
TByteSetHelper=record helper for TByteSet

 

In der Definition des TByteSetHelper können wir Folgendes haben:

public
procedure Clear;
procedure Include(const value : Byte); overload; inline;
procedure Include(const values : TByteSet); overload; inline;
procedure Exclude(const value : Byte); overload; inline;
procedure Exclude(const values : TByteSet); overload; inline;
function Intersect(const values : TByteSet) : TByteSet; inline;
function IsEmpty : boolean; inline;
function Includes(const value : Byte) : boolean; overload; inline;
function Includes(const values : TByteSet) : boolean; overload; inline;
function IsSuperSet(const values : TByteSet) : boolean; inline;
function IsSubSet(const values : TByteSet) : boolean; inline;
function Equals(const values : TByteSet) : boolean; inline;
function ToString : string; inline;
end;

{ TByteSetHelper }
procedure TByteSetHelper.Include(const value: Byte);
begin
System.Include(self, value);
end;
procedure TByteSetHelper.Exclude(const value: Byte);
begin
System.Exclude(self, value);
end;
procedure TByteSetHelper.Clear;
begin
self := [];
end;
function TByteSetHelper.Equals(const values: TByteSet): boolean;
begin
result := self=values;
end;
procedure TByteSetHelper.Exclude(const values: TByteSet);
begin
self := self - values;
end;
procedure TByteSetHelper.Include(const values: TByteSet);
begin
self := self + values;
end;
function TByteSetHelper.Includes(const values: TByteSet): boolean;
begin
result := IsSuperSet(values);
end;
function TByteSetHelper.Intersect(const values: TByteSet) : TByteSet;
begin
result := self * values;
end;
function TByteSetHelper.Includes(const value: Byte): boolean;
begin
result := value in self;
end;
function TByteSetHelper.IsEmpty: boolean;
begin
result := self=[];
end;
function TByteSetHelper.IsSubSet(const values: TByteSet): boolean;
begin
result := self <= values;
end;
function TByteSetHelper.IsSuperSet(const values: TByteSet): boolean;
begin
result := self >= values;
end;
function TByteSetHelper.ToString: string;
var
b : Byte;
begin
for b in self do
result := result + IntToStr(b) + ', ';
result := Copy(result, 1, -2 + Length(result));
end;

var
daysAsByteSet : TByteSet;
begin
daysAsByteSet.Clear;
daysAsByteSet.Include(Monday.AsByte);
daysAsByteSet.Include(Integer(Saturday);
daysAsByteSet.Include(Byte(TDay.Tuesday));
daysAsByteSet.Include(Integer(TDay.Wednesday));
daysAsByteSet.Include(Integer(TDay.Wednesday)); //2nd time - no sense
daysAsByteSet.Exclude(TDay.Tuesday.AsByte);
ShowMessage(daysAsByteSet.ToString);
ShowMessage(BoolToStr(daysAsByteSet.IsSuperSet([Monday.AsByte,Saturday.AsByte]), true));
end;

 

Es gibt ein aber 🙁

Beachten Sie, dass TByteSet Bytewerte akzeptiert – und jeder solche Wert wird hier akzeptiert. Der oben implementierte TByteSetHelper ist kein strenger Aufzählungstyp (dh Sie können ihn mit einem Nicht-TDay-Wert füttern) … aber solange ich weiß, funktioniert er für mich.

Similar Posts

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.