Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Integer-Aufzählungstyp deklarieren (https://www.delphipraxis.net/90806-integer-aufzaehlungstyp-deklarieren.html)

MatthiasR 24. Apr 2007 09:15


Integer-Aufzählungstyp deklarieren
 
Gibt es eine Möglichkeit, in Delphi einen eigenen Typ zu deklarieren, der nur aus einer bestimmten Menge aus Integerwerten besteht? Also so in der Art:
Delphi-Quellcode:
type TMyType = (1, 5, 48, 1337, 4711);
Und wenn ich mir dann von diesem Typ eine Variable erzeuge und der dann zur Laufzeit einen andren Wert zuweisen möchte (bspw: 123), dass ich dann eine Exception bekomme? So in der Art hatte ichs schon probiert:
Delphi-Quellcode:
type TMyType = (myValue1 = 1, myValue2 = 5, myValue3 = 48, myValue4 = 1337, myValue5 = 4711);
Danach dann die Bereichsüberprüfung von Delphi angeschaltet mit {$R+}, aber zur Laufzeit ging das trotzdem noch:
Delphi-Quellcode:
var
  myType: TMyType;
  // ...

procedure blabla;
begin
  myType := TMyType(123);
end;
Und danach hat die Variable myType wirklich auf ein nicht vorhandenes Element mit Index 123 gezeigt.

matashen 24. Apr 2007 09:53

Re: Integer-Aufzählungstyp deklarieren
 
Hallo,

ich bin mir da nicht sicher, aber vieleicht sollte man das mit const machen, also eine Konstante verwenden. Meines Wissens lassen sich Konstanten nicht ändern. Ob dann auf ein nicht vorhandenes Array der Zugriff erlaubt ist weis ich auch nicht. Mußt halt mal probieren.

Notfalls könntest dus auch mit ner Krücke machen, also nicht so elegant aber mit sicherheit funktionierts. Also die Werte mit trennzeichen in einen WideString schreiben und per pos suchen etwa so:

Delphi-Quellcode:
var ws:widestring;
..
.
ws:='-'+inttostr(myint1)+'-'+inttostr(myint2)+'-'+inttostr(myint3)'-'+
.
..
if pos('-'+suchstring+'-')>0 then blabla else blabla

Gruß Matthias

MatthiasR 24. Apr 2007 10:40

Re: Integer-Aufzählungstyp deklarieren
 
Wie meinst du das mit der Konstante? Und was meinst du mit dem Array? Ich verwende hier doch überhaupt kein Array.

sirius 24. Apr 2007 10:52

Re: Integer-Aufzählungstyp deklarieren
 
Wie wärs mit ner Klasse.

Das ist sicherlich ausbaufähig:
Delphi-Quellcode:
type TIntArray=array of integer;
type MyIntegerException=class(Exception);
type TMyInteger=class
       constructor Create(values:array of integer);
       destructor Destroy; override;
      private
       FAllowedValues:TIntArray;
       FValue:Integer;
       procedure setvalue(newValue:integer);
       procedure setAllowedValues(newvalues:TIntArray);
       function inside(value:integer):boolean;
      public
        property AllowedValues:TIntArray read FAllowedValues write setAllowedValues;
        property Value:Integer read FValue write setvalue;
        class function Array2IntArray(values:array of integer):TIntarray;
end;
Delphi-Quellcode:
constructor TmyInteger.Create(values:array of integer);
begin
  inherited create;
  FValue:=0;
  Allowedvalues:=Array2IntArray(values);
end;
destructor TmyInteger.Destroy;
begin
  finalize(FAllowedValues);
  inherited;
end;
function TMyInteger.inside(value:integer):boolean;
var i:integer;
begin
  result:=false;
  for i:=0 to high(FAllowedvalues) do begin
    result:=result or (Fallowedvalues[i]=value);
    if result then break;
  end;
end;
procedure TMyInteger.setAllowedValues(newvalues:TIntArray);
begin
  FallowedValues:=copy(newvalues);
  if (not inside(FValue))and(length(FAllowedValues)>0)
   then Fvalue:=FAllowedValues[0];

end;
procedure TmyInteger.setvalue(newValue:integer);
begin
  if inside(newvalue) then FValue:=newvalue
  else raise MyIntegerException.CreateFmt('%d ist kein %s-Typ!',[newvalue,self.ClassName]);
end;
class function TmyInteger.array2IntArray(values:array of integer):TIntArray;
var i:integer;
begin
  setlength(result,length(values));
  for i:=0 to high(values) do result[i]:=values[i];
end;
Anwendung:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var int:tmyinteger;
begin
  int:=tmyinteger.Create([1,2,3,4]);
  try
    int.Value:=3;

    //int.Value:=5;

    int.AllowedValues:=int.Array2IntArray([10,20,30]);
    int.Value:=10;
    int.Value:=int.value+2;

  finally
    int.free;
  end;

end;

matashen 24. Apr 2007 11:30

Re: Integer-Aufzählungstyp deklarieren
 
Ich hoffe ich hab das Problem richtig begriffen. :gruebel:

du definierst hier einen Type=(1,2,3,4)

damit hast du ja schon ein array und zwar mit 1,2,3,4 oder sehe ich da was falsch...

unter Pascal=Delphi gibt es doch neben
var a:string;
auch
const a:string='Hallo';
und const können nicht verändert werden

wenn man also den schnippsel
Delphi-Quellcode:
var
  myType: TMyType;
  // ...
hier also das ganze so einbindet

Delphi-Quellcode:
const maytype:Tmytype=(12,123,145,210)
dann können die werte nicht geändert werden.

aber wie gesagt du mußt es ausprobieren, bin mir nicht sicher ob das funzt


@sirius: Ist das Bilden einer Klasse nicht ein größerer Aufwand und wesentlich mehr Text?

sirius 24. Apr 2007 12:07

Re: Integer-Aufzählungstyp deklarieren
 
Zitat:

@sirius: Ist das Bilden einer Klasse nicht ein größerer Aufwand und wesentlich mehr Text?
War ja nur ne Idee. Wenn du was einfacheres hast.....nur zu

Hawkeye219 24. Apr 2007 12:43

Re: Integer-Aufzählungstyp deklarieren
 
Hallo,

noch ein Vorschlag:

Delphi-Quellcode:
// uses TypInfo

type
  TMyType = (vNAN, v1, v5, v48, v1337, v4711);

function IntToMyType (aValue: Integer): TMyType;
begin
  aValue := GetEnumValue(TypeInfo(TMyType), 'v' + IntToStr(aValue));
  if (aValue >= 0) then
    Result := TMyType(aValue)
  else
    Result := vNAN;
end;

function MyTypeToInt (aValue: TMyType): Integer;
var
  s : string;
begin
  s := GetEnumName(TypeInfo(TMyType), Ord(aValue));
  Result := StrToIntDef(Copy(s, 2, MaxInt), -1);
end;

// Anwendung

var
  myValue : TMyType;
  intValue : Integer;
begin
  myValue := IntToMyType(48);
  myValue := IntToMyType(100);

  intValue := MyTypeToInt(v1337);
  intValue := MyTypeToInt(vNAN);
end;
Es sollte aber klar sein, daß solche Operationen eine Laufzeitverschlechterung mit sich bringen.

Gruß Hawkeye

MatthiasR 24. Apr 2007 12:56

Re: Integer-Aufzählungstyp deklarieren
 
Erstmal danke für eure Bemühungen!

Die gebrachten Ansätze sind aber für meinen Zweck zu komplex. Das qäre quasi mit Kanonen auf Spatzen geschossen. Aber nun weiß ich zumindest, dass es so eine Möglichkeit, wie ich sie gesucht habe, wohl nicht gibt. Dann belasse ich wohl bei meiner Möglichkeit mit
Delphi-Quellcode:
type TMyType = (myValue1 = 1, myValue2 = 5, myValue3 = 48, myValue4 = 1337, myValue5 = 4711)
und überprüfe anschließend per Hand, ob die Werte auch wirklich erlaubt sind.

Muetze1 24. Apr 2007 23:16

Re: Integer-Aufzählungstyp deklarieren
 
Das Problem oben in deinem Code ist ausschliesslich, dass du mit
Delphi-Quellcode:
TMyType(123);
einen harten Typecast machst und damit die Typprüfung von Delphi explizit umgehst bzw. aussen vorlässt. Wenn du aber dem Typ etwas zuweisen willst, was in der Definitionsliste deines Enums nicht auftaucht, dann erscheint auch eine entsprechende Compilermeldung.

Deine Zuweisung sagt Delphi: "Schreib mit da 123 in die Variable - mir egal, dass es der Typ ist". Wenn du aber zur Laufzeit eine so wie vorne zugewiesene Variable zuweist auf einen anderen vom Typ TMyType, dann wird nur der Inhalt kopiert bzw. zugewiesen und keine Typprüfung durchgeführt...


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