Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Kann ich eine abstrakte Klasse ohne Warnung erstellen? (https://www.delphipraxis.net/206233-kann-ich-eine-abstrakte-klasse-ohne-warnung-erstellen.html)

Der schöne Günther 2. Dez 2020 07:06

Delphi-Version: 10.4 Sydney

Kann ich eine abstrakte Klasse ohne Warnung erstellen?
 
Ich erstelle eine Unterklasse von einem
Delphi-Quellcode:
System.IniFiles.TCustomIniFile
mit seinen zwei Dutzend
Delphi-Quellcode:
virtual abstract
Methoden.

Ich gehe nun nicht hin und implementiere für jede Methode ein
Delphi-Quellcode:
override
sondern erstelle mir einmal einen
Delphi-Quellcode:
System.Rtti.TVirtualMethodInterceptor
und intercepte einfach alle meine virtuellen Methoden. Das klappt super.

Problem: Dort wo ich nun eine Instanz meiner Klasse erstelle erhalte ich, nicht ganz unberechtigt, eine Warnung
Code:
[dcc32 Warning] Project1.dpr(26): W1020 Constructing instance of 'TTest' containing abstract method 'TBase.SomeMethod'
.

Die Warnung zeigt auf jede Zeile welche das Create aufruft, nicht auf die Klasse selbst. Ich kann mir also auch nicht helfen wenn ich die Warnung dort abschalte.

Wie komme ich hier wieder raus?

Ich gebe am besten das konkrete Beispiel:

interface
Delphi-Quellcode:
uses
  System.SysUtils,
  System.Rtti,
  System.IniFiles;

type
   TDelegateIni = class(TCustomIniFile)
   protected var
      delegate: TCustomIniFile;
      interceptor: TVirtualMethodInterceptor;
   public
      constructor Create(const delegate: TCustomIniFile);
      destructor Destroy(); override;
   end;

implementation
Delphi-Quellcode:
constructor TDelegateIni.Create(const delegate: TCustomIniFile);
begin
   inherited Create(String.Empty);
   self.delegate := delegate;
   interceptor := TVirtualMethodInterceptor.Create(ClassType);
   interceptor.OnBefore :=
      procedure(
         Instance: TObject;
         Method: TRttiMethod;
         const Args: TArray<TValue>;
         out DoInvoke: Boolean;
         out Result: TValue
      )
      begin
         DoInvoke := False; // all methods are virtual abstract
         Result := Method.Invoke(delegate, Args);
      end;
   interceptor.Proxify(self);
end;

destructor TDelegateIni.Destroy();
begin
   if Assigned(interceptor) then
      begin
         interceptor.Unproxify(self);
         interceptor.Destroy();
      end;
    delegate.Free();

   inherited;
end;

jaenicke 2. Dez 2020 07:32

AW: Kann ich eine abstrakte Klasse ohne Warnung erstellen?
 
Das wirst du nicht ändern können. Solche Tricks haben eben auch Nachteile. ;-)

himitsu 2. Dez 2020 18:19

AW: Kann ich eine abstrakte Klasse ohne Warnung erstellen?
 
Jupp, von TCustomIniFile einen Nachfahren und dann dort alle abstrakten Methoden "leer" Implementieren,
dann bekommst keine Warnungen mehr und du kannst dich in Ruhe mit dem Interceptor drangängen.
Oder es gleich richtig implementieren, denn der Interceptor ist saulangsam.

Man kann zwar diese Warnung abschalten (wenn man zu dem Fehlercode die Hilfe lesen würde),
Delphi-Quellcode:
{$WARN CONSTRUCTING_ABSTRACT OFF} ... {$WARN CONSTRUCTING_ABSTRACT DEFAULT}

obwohl ich sie viel lieber von Warnung auf Fehler umstellen würde,
Delphi-Quellcode:
{$WARN CONSTRUCTING_ABSTRACT ERROR}

denn wer sowas abstraktes abstruses macht, der gehört eigentlich richtig doll verhauen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19: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