AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi RTTI: Wie kann ich prüfen, ob ein Feld vom Typ einer Klasse ist?
Thema durchsuchen
Ansicht
Themen-Optionen

RTTI: Wie kann ich prüfen, ob ein Feld vom Typ einer Klasse ist?

Ein Thema von Der schöne Günther · begonnen am 24. Apr 2014 · letzter Beitrag vom 24. Apr 2014
Antwort Antwort
Der schöne Günther

Registriert seit: 6. Mär 2013
6.158 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

RTTI: Wie kann ich prüfen, ob ein Feld vom Typ einer Klasse ist?

  Alt 24. Apr 2014, 12:56
Delphi-Version: XE5
Und ich dachte, ich könnte mit der RTTI umgehen.

Folgendes:
Delphi-Quellcode:
type
   TBaseClass = class(TObject);
   TSubClass = class(TBaseClass);

   TMyContainer = class
      first: TBaseClass;
      second: TSubClass;
      third: TObject;
   end;
Ich möchte alle Felder in TMyContainer finden, die zuweisungskompatibel zu TBaseClass sind. Also first und second .

Wie tue ich das? Mir fällt nichts anderes ein, als nur strikt Typ mit Typ vergleichen zu können.

Folgengender Code
Delphi-Quellcode:
var
   context: TRttiContext;
   fieldIterator: TRttiField;

begin
   context := TRttiContext.Create();

   for fieldIterator in context.GetType(TMyContainer).GetFields() do begin
      WriteLn( 'Feld gefunden: '+fieldIterator.Name.QuotedString() );

      if fieldIterator.FieldType = context.GetType(TBaseClass) then
         WriteLn('Das Feld ist eine zu TBaseClass kompatible Instanz');

      if Assigned(fieldIterator.FieldType.BaseType) then
         WriteLn('BaseType-Name: '+fieldIterator.FieldType.BaseType.Name);

      WriteLn(EmptyStr);
   end;

   ReadLn;
end.
ergibt
Code:
Feld gefunden: 'first'
Das Feld ist eine zu TBaseClass kompatible Instanz
BaseType-Name: TObject

Feld gefunden: 'second'
BaseType-Name: TBaseClass

Feld gefunden: 'third'
Man sieht:
  • TBaseClass leitet sich ab von TObject
  • TSubClass leitet sich ab von TBaseClass
  • TObject leitet sich von nichts ab

Nur: Muss ich jetzt für jedes Feld die gesamte Vererbungshierarchie bis TObject hochkrabbeln um zu schauen, ob meine gewollte Basisklasse einmal vorkommt?

Frage: Gibt es in der RTTI nichts wie das normale InheritsFrom(..) bzw. den is -Operator?
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.158 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: RTTI: Wie kann ich prüfen, ob ein Feld vom Typ einer Klasse ist?

  Alt 24. Apr 2014, 13:11
PS: Das in eine Helfer-Klasse zu packen war jetzt kein Ding, aber mir kommt es trotzdem komisch vor. Gibt es da nichts fertiges in der RTTI?


Delphi-Quellcode:
unit RttiTypeHelper;

interface

uses System.Rtti;

type
   TRttiTypeHelper = class helper for TRttiType
      private const
         Para_inheritsFromType_includeCurrent = True;

      public
         function inheritsFromType(
            const    baseType:    TRttiType;
            const includeCurrent: Boolean = Para_inheritsFromType_includeCurrent
         ): Boolean; overload;

         function inheritsFromType(
            const    baseClass:    TClass;
            const includeCurrent: Boolean = Para_inheritsFromType_includeCurrent
         ): boolean; overload;
   end;

implementation

function TRttiTypeHelper.inheritsFromType(
   const    baseType:    TRttiType;
   const includeCurrent: Boolean = Para_inheritsFromType_includeCurrent
): Boolean;
var
   currentClassType: TRttiType;
begin
   Result := False;

   if not includeCurrent then
      currentClassType := self.baseType
   else
      currentClassType := self;

   while (not Result) and Assigned(currentClassType) do begin
         if currentClassType = baseType then
            Result := True;
         currentClassType := currentClassType.baseType;
      end;
end;

function TRttiTypeHelper.inheritsFromType(
   const    baseClass:    TClass;
   const includeCurrent: Boolean = Para_inheritsFromType_includeCurrent
): Boolean;
var
   rttiContext: TRttiContext;
begin
   rttiContext := TRttiContext.Create();
   Result := inheritsFromType( rttiContext.GetType(baseClass), includeCurrent);
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#3

AW: RTTI: Wie kann ich prüfen, ob ein Feld vom Typ einer Klasse ist?

  Alt 24. Apr 2014, 13:27
Delphi-Quellcode:
      if fieldIterator.FieldType.IsInstance then begin
        if fieldIterator.FieldType.AsInstance.MetaclassType.InheritsFrom(TBaseClass) then begin
          WriteLn('Das Feld ist eine zu TBaseClass kompatible Instanz');
        end;
      end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.158 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: RTTI: Wie kann ich prüfen, ob ein Feld vom Typ einer Klasse ist?

  Alt 24. Apr 2014, 13:52
Genau das!

Herzlichen Dank. Wesentlich kürzer
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:22 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz