AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Generics: Instanz-Erzeugung in generischer Klasse
Thema durchsuchen
Ansicht
Themen-Optionen

Generics: Instanz-Erzeugung in generischer Klasse

Offene Frage von "hokuspokussimsalabim"
Ein Thema von Sir Rufo · begonnen am 9. Okt 2011 · letzter Beitrag vom 10. Okt 2011
 
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

Generics: Instanz-Erzeugung in generischer Klasse

  Alt 9. Okt 2011, 22:03
Ich habe hier eine generische Klassen/Interface Definition, die von TComponent abgeleitet ist.

Wie bekomme ich die Klasse jetzt dazu eine passende Instanz zu erzeugen?
TGenClass<T:Class, Constructor> = class sagt ja nur aus, dass die Klasse T einen parameterlosen Constructor hat.
TComponent hat aber einen Constructor mit Parameter (obwohl ich dem ledigleich ein schnödes nil mitgeben würde).
Das T.Create; findet der Compiler gut, aber es ist nicht so wie ich das möchte, denn
Delphi-Quellcode:
var
  MyButton : IGenericLink<TButton>;
begin
  MyButton := TGenericLink<TButton>.Create;
  MyButton.Link.OnClick := ButtonClick; // hier rummst es, und das soll es nicht
end;
und T.Create(nil); findet der Compiler total blöde

Sinn und Zweck dieser Übung ist das Binding von Komponenten einer Form zu einer Controller-Unit.
Dabei soll es die Controller-Unit aushalten, wenn auf der Form nicht alle Komponenten vorhanden sind. (Darum hält TGenericLink eben ein Dummy-Object vor, auf das zugegriffen wird, wenn kein gültiger Link gebildet werden konnte).

Wer kann mir da mal auf den lahmen Gaul helfen?

Die ganze Unit mal zum überfliegen:
Delphi-Quellcode:
unit FormBinding;

interface

uses
  Classes;

type
  IGenericLink<T: TComponent, Constructor> = interface
    ['{7650F483-5FDD-431F-96D1-65536B127BB5}']
    function GetLink: T;
    procedure SetLink(const Value: T);
    property Link: T read GetLink write SetLink;
    procedure LinkTo(const Value: TComponent); overload;
    procedure LinkTo(const Owner: TComponent;
      const ComponentName: string); overload;
    function IsLinked: Boolean;
    function GetOnLinkChanged: TNotifyEvent;
    procedure SetOnLinkChanged(const Value: TNotifyEvent);
    property OnLinkChanged: TNotifyEvent read GetOnLinkChanged
      write SetOnLinkChanged;
  end;

  TGenericLink<T: TComponent, Constructor> = class(TInterfacedObject,
    IGenericLink<T>)
  private
    fInt: T;
    fExt: T;
    fOnLinkChanged: TNotifyEvent;
    function GetLink: T;
    procedure SetLink(const Value: T);
    function GetOnLinkChanged: TNotifyEvent;
    procedure SetOnLinkChanged(const Value: TNotifyEvent);
  public
    constructor Create;
    destructor Destroy; override;
    property Link: T read GetLink write SetLink;
    procedure LinkTo(const Value: TComponent); overload;
    procedure LinkTo(const Owner: TComponent;
      const ComponentName: string); overload;
    function IsLinked: Boolean;
    property OnLinkChanged: TNotifyEvent read GetOnLinkChanged
      write SetOnLinkChanged;
  end;

implementation

{ TGenericLink<T> }

constructor TGenericLink<T>.Create;
begin
  inherited Create;
  fInt := T.Create; // <<-- ???
end;

destructor TGenericLink<T>.Destroy;
begin
  fInt.Free;
  inherited;
end;

function TGenericLink<T>.GetLink: T;
begin
  if Assigned(fExt) then
    Result := fExt
  else
    Result := fInt;
end;

function TGenericLink<T>.GetOnLinkChanged: TNotifyEvent;
begin
  Result := fOnLinkChanged;
end;

function TGenericLink<T>.IsLinked: Boolean;
begin
  Result := Assigned(fExt);
end;

procedure TGenericLink<T>.LinkTo(const Owner: TComponent;
  const ComponentName: string);
begin
  LinkTo(Owner.FindComponent(ComponentName));
end;

procedure TGenericLink<T>.LinkTo(const Value: TComponent);
begin
  if Assigned(Value) and Value.InheritsFrom(T) then
    SetLink(Value)
  else
    SetLink(nil);
end;

procedure TGenericLink<T>.SetLink(const Value: T);
begin
  fExt := Value;
  if Assigned(OnLinkChanged) then
    OnLinkChanged(Self);
end;

procedure TGenericLink<T>.SetOnLinkChanged(const Value: TNotifyEvent);
begin
  fOnLinkChanged := Value;
end;

end.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo ( 9. Okt 2011 um 22:07 Uhr)
  Mit Zitat antworten Zitat
 


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 06:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz