Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Generic und Wildcards (https://www.delphipraxis.net/169764-generic-und-wildcards.html)

QStorm 10. Aug 2012 08:34

Generic und Wildcards
 
Hallo,

Gibt es in Delphi die Möglichkeit Platzhalter (Wildcards) anstelle von konkreten Typen bei der Erzeugung eines generischen Typen zu benutzen?

Von Java kenne ich folgendes:
Code:
ArrayList<Task<?>> entries = new ArrayList<Task<?>>();
Wobei Task irgendeine generische Klasse ist.

Nun suche ich etwas äquivalentes in Delphi:
Code:
Entries : TList<Task<?>>;
Vielen Dank im voraus. :)

/QStorm

himitsu 10. Aug 2012 08:46

AW: Generic und Wildcards
 
Nein, da in Delphi eine strikte Typprüfung vorherscht, mußt du den Typen, bei Verwendung, auch vollständig deklarieren.

Delphi-Quellcode:
Task<TAbc>
und
Delphi-Quellcode:
Task<TXyz>
sind zwei vollkommen unterschiedliche Typen, welche auch nicht miteinander kompatibel sind.


Was du machen kannst, sind generische Funktionen.

Delphi-Quellcode:
type
  TMyList = class(TList) // oder TMyList<X> = class(TList<X>)
    function SetValue<T>(const Value: T);
    procedure GetValue<T>: T;
  end;
Ob sowas auch geht, weiß ich noch nicht
Delphi-Quellcode:
property Value<T>: T read GetValue<T> write SetValue<T>;
(vergessen zu testen).

s.h.a.r.k 10. Aug 2012 08:46

AW: Generic und Wildcards
 
Wüsste nicht, dass es sowas gibt. Aber wo ist das Problem folgendes zu definiern?
Delphi-Quellcode:
type
TMyGenericList<InnerType> = TList<TList<InnerType>>;
Oder habe ich den Sinn des ? falsch verstanden?

Iwo Asnet 10. Aug 2012 09:36

AW: Generic und Wildcards
 
Meine Erfahrung zeigt: Wenn man mit Generics anfängt, muss man das gnadenlos durchziehen, d.h. entweder mit Metaklassen arbeiten oder mit Generics. Die Programmierparadigmen beider Systeme widersprechen sich: Bei Generics will ich vorher wissen, mit wem ich es zu tun habe, bei Metaklassen nicht.

Du könntest es über ein Interface versuchen: In C# geht sowas:
Code:
private IList CreateGenericList(Type listItemType)
{
   Type listType = typeof (List<>);
   Type combinedType = listType.MakeGenericType(listItemType);
   return (IList) Activator.CreateInstance(combinedType);
}
Vielleicht (vermutlich) kann man das auch in Delphi nachbilden.

Elvis 10. Aug 2012 13:42

AW: Generic und Wildcards
 
In Java geht das, weil Java, als Runtime, gar keine Generics hat.
Der Java-Compiler benutzt eine gleichnamige Klasse ohne Typenparameter und casted sich überall einen Wolf.

Wenn du es auf einen Nenner runterbringen willst, dann nur über eine Liste eines nicht-generischen Vorfahren oder Interfaces.

Seit D2010 (?) kann Delphi ein bissel RTTI, und seitdem kann man auch verschiedene Typen in einen Typen verallgeimeinern: TValue

Hier ist mal ein Beispiel, falls ich mich nicht klar ausdrücken konnte...
Delphi-Quellcode:
type
  TTask = class abstract
  protected
    function GetValue : TValue; virtual; abstract;
  public
    property Value : TValue read GetValue;
  end;

  TTask<T> = class(TTask)
  private
    FValue: T;
    procedure SetValue(const Value: T);
  protected
    function GetValue : TValue; override;
  public
    property Value : T read FValue write SetValue;
    constructor Create(value : T);
end;

constructor TTask<T>.Create(value: T);
begin
  FValue := value;
end;

function TTask<T>.GetValue: TValue;
begin
  result := TValue.From<T>(Value);
end;

procedure TTask<T>.SetValue(const Value: T);
begin
  FValue := Value;
end;

var
  tasks : TList<TTask>;
  task : TTask;
begin
  tasks := TList<TTask>.Create();
  tasks.Add(TTask<Integer>.Create(1));
  tasks.Add(TTask<String>.Create('Hallo'));
  tasks.Add(TTask<Double>.Create(1.2345));

  for task in tasks do
    Writeln(task.Value.ToString());
end.


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