Helpers van Delphi Class (en Record) begrijpen

Een functie van de Delphi-taal die enkele jaren geleden is toegevoegd (terug in Delphi 2005) genaamd "Class Helpers" is ontworpen om u nieuwe functionaliteit toe te voegen aan een bestaande klasse (of een record) door nieuwe methoden aan de klasse te introduceren (record).

Hieronder zie je nog een aantal ideeën voor klashelpers + leer wanneer en wanneer je klashelpers niet moet gebruiken.

Klassehulp voor ...

In eenvoudige woorden, een klassehulp is een constructie die een klasse uitbreidt door nieuwe methoden in de hulpklasse te introduceren. Met een klassenhelper kunt u de bestaande klasse uitbreiden zonder deze daadwerkelijk te wijzigen of ervan te erven.

Om de TStrings-klasse van de VCL uit te breiden, zou je een klassehelper als volgt declareren en implementeren:

 type TStringsHelper = klassenhulp voor TStrings openbaar functie bevat (const aString: string): boolean; einde; 

De bovenstaande klasse, "TStringsHelper" genoemd, is een klassehulp voor het type TStrings. Merk op dat TStrings is gedefinieerd in de Classes.pas, een eenheid die standaard beschikbaar is in de gebruiksclausule voor elke eenheid van een Delphi-formulier, bijvoorbeeld.

De functie die we aan het type TStrings toevoegen met behulp van onze klassehelper is "Bevat". De implementatie kan er uitzien als:

 functie TStringsHelper.Contains (const aString: string): boolean; beginnen resultaat: = -1 IndexOf (aString); einde; 

Ik weet zeker dat je het bovenstaande vaak in je code hebt gebruikt - om te controleren of sommige afstammelingen van TStrings, zoals TStringList, een stringwaarde hebben in de Items-collectie.

Merk op dat bijvoorbeeld de eigenschap Items van een TComboBox of een TListBox van het type TStrings is.

Nadat de TStringsHelper is geïmplementeerd en een keuzelijst op een formulier ("ListBox1" genoemd), kunt u nu controleren of een string deel uitmaakt van de eigenschap Items van de keuzelijst met behulp van:

 als ListBox1.Items.Contains ('some string') vervolgens... 

Klassehelpers gaan en NoGo

De implementatie van klassenhulppers heeft een aantal positieve en sommige (u zou kunnen denken aan) negatieve gevolgen voor uw codering.

Over het algemeen moet je voorkomen dat je je eigen klassen uitbreidt - alsof je wat nieuwe functionaliteit aan je eigen aangepaste klassen moet toevoegen - voeg de nieuwe dingen rechtstreeks in de klassenimplementatie toe - zonder een klassenhulp te gebruiken.

Klassehelpers zijn daarom meer ontworpen om een ​​klasse uit te breiden wanneer u niet kunt (of hoeft te) vertrouwen op normale klassenovererving en interface-implementaties.

Een klassenhelper kan geen instantiegegevens declareren, zoals nieuwe privévelden (of eigenschappen die dergelijke velden zouden lezen / schrijven). Het toevoegen van nieuwe klassenvelden is toegestaan.

Een klassenhelper kan nieuwe methoden toevoegen (functie, procedure).

Vóór Delphi XE3 kon je alleen klassen en records uitbreiden - complexe typen. Vanaf de release van Delphi XE 3 kun je ook eenvoudige typen uitbreiden zoals integer of string of TDateTime, en een constructie hebben zoals:

 var s: string; beginnen s: = 'Delphi XE3 helpers'; s: = s.UpperCase.Reverse; einde; 

Ik zal in de nabije toekomst over Delphi XE 3 eenvoudig type helper schrijven.

Waar is MIJN Klassehelper

Een beperking op het gebruik van klassenhulpen die u kunnen helpen "uzelf in de voet te schieten" is het feit dat u meerdere helpers kunt definiëren en aan één type kunt koppelen. Er is echter slechts nul of één helper van toepassing op een specifieke locatie in de broncode. De helper die is gedefinieerd in de dichtstbijzijnde scope is van toepassing. Klasse of record helper scope wordt bepaald op de normale Delphi-manier (bijvoorbeeld van rechts naar links in de gebruiksclausule van de eenheid).

Dit betekent dat u twee helpers van de TStringsHelper-klasse in twee verschillende eenheden kunt definiëren, maar er slechts één van toepassing is wanneer deze daadwerkelijk wordt gebruikt!

Als een klassehelper niet is gedefinieerd in de eenheid waar u de geïntroduceerde methoden gebruikt - wat in de meeste gevallen het geval zal zijn, weet u niet welke klassehelperimplementatie u eigenlijk zou gebruiken. Twee klasse helpers voor TStrings, anders genoemd of woonachtig in verschillende eenheden, kunnen een verschillende implementatie hebben voor de "Bevat" -methode in het bovenstaande voorbeeld.

Gebruik of niet?

Ja, maar let op de mogelijke bijwerkingen.

Hier is nog een handige uitbreiding van de bovengenoemde helper van de TStringsHelper-klasse

 TStringsHelper = klassenhulp voor TStrings privaat functie GetTheObject (const een draad: draad): TObject; procedure SetTheObject (const een draad: draad; const Waarde: TObject); openbaar eigendom ObjectFor [const een draad : draad]: TObject lezen GetTheObject schrijven SetTheObject; einde; ... functie TStringsHelper.GetTheObject (const een draad: draad): TObject; var idx: geheel getal; beginnen resultaat: = nul; idx: = IndexOf (aString); als idx> -1 vervolgens result: = Objecten [idx]; einde; procedure TStringsHelper.SetTheObject (const een draad: draad; const Waarde: TObject); var idx: geheel getal; beginnen idx: = IndexOf (aString); als idx> -1 vervolgens Objecten [idx]: = Waarde; einde; 

Als u objecten aan een stringlijst hebt toegevoegd, kunt u raden wanneer u de bovenstaande handige helper-eigenschap gebruikt.