![]() |
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:
Wobei Task irgendeine generische Klasse ist.
ArrayList<Task<?>> entries = new ArrayList<Task<?>>();
Nun suche ich etwas äquivalentes in Delphi:
Code:
Vielen Dank im voraus. :)
Entries : TList<Task<?>>;
/QStorm |
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:
und
Task<TAbc>
Delphi-Quellcode:
sind zwei vollkommen unterschiedliche Typen, welche auch nicht miteinander kompatibel sind.
Task<TXyz>
Was du machen kannst, sind generische Funktionen.
Delphi-Quellcode:
Ob sowas auch geht, weiß ich noch nicht
type
TMyList = class(TList) // oder TMyList<X> = class(TList<X>) function SetValue<T>(const Value: T); procedure GetValue<T>: T; end;
Delphi-Quellcode:
(vergessen zu testen).
property Value<T>: T read GetValue<T> write SetValue<T>;
|
AW: Generic und Wildcards
Wüsste nicht, dass es sowas gibt. Aber wo ist das Problem folgendes zu definiern?
Delphi-Quellcode:
Oder habe ich den Sinn des ? falsch verstanden?
type
TMyGenericList<InnerType> = TList<TList<InnerType>>; |
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:
Vielleicht (vermutlich) kann man das auch in Delphi nachbilden.
private IList CreateGenericList(Type listItemType)
{ Type listType = typeof (List<>); Type combinedType = listType.MakeGenericType(listItemType); return (IList) Activator.CreateInstance(combinedType); } |
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 11:11 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