Einzelnen Beitrag anzeigen

Der schöne Günther

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

Kann ich eine abstrakte Klasse ohne Warnung erstellen?

  Alt 2. Dez 2020, 07:06
Delphi-Version: 10.4 Sydney
Ich erstelle eine Unterklasse von einem System.IniFiles.TCustomIniFile mit seinen zwei Dutzend virtual abstract Methoden.

Ich gehe nun nicht hin und implementiere für jede Methode ein override sondern erstelle mir einmal einen 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;
  Mit Zitat antworten Zitat