![]() |
Delphi-Version: 5
Generics mit Einschränkungen auf Ordinaltypen?
Morgen Jungs :-D
Ich wollte mich mal wieder den Generics bedienen. Das Problem ist, dass ich als Typparameter nur Ordinaltypen verwenden will und werde. Diese Einschränkung ist ja aber leider nicht möglich. Ich brauche sie aber, da ich Konstrukte nutzen muss die nur mit Ordinaltypen funktionieren (z.B. für Schleifen, für die Größenangabe bei Arrays, etc.). Irgendeine Idee? :lol: |
AW: Generics mit Einschränkungen auf Ordinaltypen?
Zitat:
Delphi-Quellcode:
Letztendlich weisst Du ja, was Du tust und musst Dich daher nicht mit constraints vor Dir selber und Deinem Handeln schützen, oder? :lol:
TFoo<T> =class
procedure TueDies: T; end; TIntegerFoo= class(TFoo<integer>); BTW, Dein Profil zeigt Delphi 5, das hat noch keine Generics! |
AW: Generics mit Einschränkungen auf Ordinaltypen?
Ja schon klar. Aber das Problem ist, dass es so nicht geht, wenn ich z.B. eine Schleife oder ein Array mit Hilfe des Typparameters programmieren will.
Delphi-Quellcode:
Das geht nicht, da Delphi - verständlicherweise - meckert, dass er für die Schleife einen Ordinaltypen braucht. Den habe ich zwar vor zu übergeben, aber davon kann Delphi ja nun mal nicht ausgehen.
TFoo<T> = class
procedure Blubb; end; procedure TFoo<T>.Blubb; var LSchleife: T; begin For LSchleife := Low(T) to High(T) do ... ; end; PS: Also bei mir zeigt mein Profil schon lange Delphi 2009 Professional an :wink: |
AW: Generics mit Einschränkungen auf Ordinaltypen?
Evtl. so:
Delphi-Quellcode:
Hab's allerdings nicht getestet, nur 'ne Idee...
TFoo<T: record> = class // Beschränkung auf Wertetypen
procedure Blubb; end; procedure TFoo<T>.Blubb; var LSchleife: T; LMin: T; LMax: T; begin if TypeInfo(T)=TypeInfo(integer) then begin LMin:= Low(integer); LMax:= High(integer); end else if TypeInfo(T)=TypeInfo(cardinal) then begin LMin:= Low(cardinal); LMax:= High(cardinal); end; // usw. For LSchleife := LMin to LMax do ... ; end; Zitat:
|
AW: Generics mit Einschränkungen auf Ordinaltypen?
[add]
selbes Grundthema: ![]() [/add] Antwort, welche ich selber bei Sowas schon gehört hab: Für sowas sind Generics nicht gedacht. Grund, Delphi verfügt nur über einen Single-Pass-Compiler, solche speziellen Typgruppen gibt es nicht (in C, wo Delphi es abgekupfert hat) und da Delphi bei Parsen dieses Codes noch nicht weiß um welchen Typ es sich irgendwann mal handeln wird, kann man auf so spezifische Eigenschaften des gewünschten Typs nicht zugreifen. Schau dir einfach mal meine letzten Threads zu den besch*** Generigs an. Mein Fazit: Generics könnten sowas von cool sein, aber für z.B. sowas wie das hier, sind die einfach nicht zu gebrauchen ... leider. :cry: @webcss: Ja, solche Hacks gehn schon, aber diese machen absolut keinen Spaß, sind umständlich, ineffektiv / teilweise Rechenintensiv, und, wenn man sie an vielen Stellen einsetzt, auch noch fehleranfällig und wartungsintensiv. Ordinale Typen gibt es viele (nicht nur diese Beiden) und ich hab es schon bei den 3 Typen AnsiString, UnicodeString und WideString aufgegeben, weil es einfach zu unübersichtlich wurde. @Deep-Sea: Verzichte einfach auf die Generics, verwende in der Klasse den Integer und eventuell noch eine zweite Klasse mit Int64 (oder so ähnlich). |
AW: Generics mit Einschränkungen auf Ordinaltypen?
Schade schade ... auch wenn ich damit eig. schon gerechnet habe ...
Zitat:
Genau deswegen wollte ich es ja so lösen, denn in dem Fall geht es mir um Enums. Aktuell wirklich nur zwei ... aber in Zukunft vlt. mal dutzende. Na mal sehen, wie ich es schön lösen kann ... Find's halt doof von Delphi, denn Interfaces kann ich auch zur Einschränkung nutzen :? @webcss: Ach da ... joa, vergessen zu setzen :stupid: |
AW: Generics mit Einschränkungen auf Ordinaltypen?
jupp, sowas wie Interface und Object kannst du als Einschränkung nutzen,
aber auch da wird letzendlich auch Vieles nicht funktionieren ... siehe mein verlinkter String-Thread, also da wo es mal um Objekte geht. |
AW: Generics mit Einschränkungen auf Ordinaltypen?
Vielleicht kannst du etwas Logik von Compilezeit in Richtung Laufzeit verschieben. Z.B. könntest du TFoo im Konstruktor eine TypeInfo übergeben und dann irgendwie so:
Delphi-Quellcode:
arbeiten. Mit der mangelnde Typsicherheit (Enum -> Integer) müsstest du bei einer Lösung mit Generics vermutlich auch leben.
function Iterate(ATypeInfo: PTypeInfo): Cardinal;
var i: Integer; TypeData: PTypeData; begin TypeData := GetTypeData(ATypeInfo); for i := TypeData^.MinValue to TypeData^.MaxValue do Writeln(GetEnumName(ATypeInfo, i)); end; begin Iterate(TypeInfo(TTypeKind)); end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:38 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-2025 by Thomas Breitkreuz